﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using ESOL.Common.Entity;
using ESOL.Business.Inv;
using BPM.Base.Tools;
using BPM.Foundation.PWService;
using ESOL.Business.Mst;
using ESOL.Common;
using ESOL.Business.Prod;
using ESOL.Business.Pur;
using System.Collections;
using Suzsoft.Smart.Data;
using AutoMapper;

namespace ESOL.Services
{
    public class InvService : IInvService
    {
        public bool TestConnect()
        {
            return true;
        }

        #region 仓库，储位
        public InvMaintainWh AddInvWh(InvMaintainWh mwh)
        {
            var addWh = new InvWhEntity();
            addWh.Id = mwh.Id;
            addWh.CreatedBy = mwh.CreatedBy;
            addWh.CreatedDate = DateTime.Now;
            addWh.UpdatedBy = mwh.UpdatedBy;
            addWh.UpdatedDate = DateTime.Now;
            addWh.IsActive = mwh.IsActive;
            addWh.WhName = mwh.WhName;
            addWh.Position = mwh.Position;
            addWh.Description = mwh.Description;
            addWh.Type = mwh.Type;
            addWh.ManagedBy = mwh.ManagedBy;
            addWh.IsLock = mwh.IsLock;
            addWh.Status = Common.WfStatus.WFS10.ToString();

            mwh.Status = addWh.Status;
            mwh.CreatedDate = DateTime.Now;
            mwh.UpdatedDate = DateTime.Now;
            if (InvWhBs.InsertInvWh(addWh))
            {
                return mwh;
            }
            else return null;
        }

        public InvMaintainWh SaveInvWh(InvMaintainWh mwh)
        {
            var wh = InvWhBs.GetInvWh(new InvWhEntity { Id = mwh.Id });
            if (wh == null)
            {
                wh = new InvWhEntity();
                wh.Id = mwh.Id;
                wh.CreatedBy = mwh.CreatedBy;
                wh.CreatedDate = DateTime.Now;
                wh.UpdatedBy = mwh.UpdatedBy;
                wh.UpdatedDate = DateTime.Now;
                wh.IsActive = mwh.IsActive;
                wh.WhName = mwh.WhName;
                wh.Position = mwh.Position;
                wh.Description = mwh.Description;
                wh.Type = mwh.Type;
                wh.ManagedBy = mwh.ManagedBy;
                wh.IsLock = mwh.IsLock;
                wh.Status = Common.WfStatus.WFS10.ToString();

                mwh.Status = wh.Status;
                mwh.CreatedDate = wh.CreatedDate;
                mwh.UpdatedDate = wh.UpdatedDate;
                if (InvWhBs.InsertInvWh(wh))
                    return mwh;
                else return null;
            }
            else
            {
                wh.UpdatedBy = mwh.UpdatedBy;
                wh.UpdatedDate = DateTime.Now;
                wh.IsActive = mwh.IsActive;
                wh.WhName = mwh.WhName;
                wh.Position = mwh.Position;
                wh.Description = mwh.Description;
                wh.Type = mwh.Type;
                wh.ManagedBy = mwh.ManagedBy;
                wh.IsLock = mwh.IsLock;
                wh.Status = mwh.Status;
                mwh.UpdatedDate = wh.UpdatedDate;
                if (InvWhBs.UpdateInvWh(wh))
                    return mwh;
                else return null;
            }
        }

        public InvMaintainWh UpdateInvWh(InvMaintainWh mwh)
        {
            if (mwh == null)
                return null;
            var updateWh = InvWhBs.GetInvWh(new InvWhEntity { Id = mwh.Id });
            if (updateWh == null)
                return null;
            updateWh.UpdatedBy = mwh.UpdatedBy;
            updateWh.UpdatedDate = mwh.UpdatedDate;
            updateWh.IsActive = mwh.IsActive;
            updateWh.WhName = mwh.WhName;
            updateWh.Position = mwh.Position;
            updateWh.Description = mwh.Description;
            updateWh.Type = mwh.Type;
            updateWh.ManagedBy = mwh.ManagedBy;
            updateWh.IsLock = mwh.IsLock;
            updateWh.Status = mwh.Status;

            mwh.UpdatedDate = DateTime.Now;
            if (InvWhBs.UpdateInvWh(updateWh))
                return mwh;
            else return null;

        }

        public int? DelInvWh(InvMaintainWh mwh)
        {
            if (mwh == null)
                return 1;
            var wh = InvWhBs.GetInvWh(new InvWhEntity { Id = mwh.Id });
            if (wh == null)
                return 2;
            var locs = InvWhLocationBs.GetWhLocsByWhId(mwh.Id);
            if (InvWhBs.DelWh(wh, locs))
                return null;
            else return -1;
        }

        public DataSet GetInvWhAllDsByCondition(InvWhQueryCondition con)
        {
            string sql = @"select wh.*,u1.firstName as CREATED_USER,u2.firstName as UPDATED_USER,u3.firstName as MANAGED_USER 
from INV_WH wh
left join BPMDB.dbo.PW_User u1 on wh.CREATED_BY=u1.userNo
left join BPMDB.dbo.PW_User u2 on wh.UPDATED_BY=u2.userNo
left join BPMDB.dbo.PW_User u3 on wh.MANAGED_BY=u3.userNo";
            return InvWhBs.GetAllDsBySql(sql);
        }

        public InvWhEntity GetInvWhEntityByKey(string whId)
        {
            if (string.IsNullOrEmpty(whId))
                return null;
            return DataAccess.SelectSingle<InvWhEntity>(new InvWhEntity { Id = whId });
        }

        public InvMaintainWh GetInvMaintainWhByKey(string whId)
        {
            if (string.IsNullOrEmpty(whId))
                return null;
            var wh = InvWhBs.GetInvWh(new InvWhEntity { Id = whId });
            if (wh == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            var mwh = new InvMaintainWh();
            mwh.Id = wh.Id;
            mwh.CreatedBy = wh.Id;
            if (!string.IsNullOrEmpty(wh.CreatedBy))
            {
                var createdUser = ps.getUser(null, wh.CreatedBy);
                mwh.CreatedUser = createdUser.firstName;
            }
            mwh.CreatedDate = wh.CreatedDate;
            mwh.UpdatedBy = wh.UpdatedBy;
            if (!string.IsNullOrEmpty(wh.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, wh.UpdatedBy);
                mwh.UpdatedUser = updatedUser.firstName;
            }
            mwh.UpdatedDate = wh.UpdatedDate;
            mwh.IsActive = wh.IsActive;
            mwh.WhName = wh.WhName;
            mwh.Position = wh.Position;
            mwh.Description = wh.Description;
            mwh.Type = wh.Type;
            mwh.ManagedBy = wh.ManagedBy;
            if (!string.IsNullOrEmpty(wh.ManagedBy))
            {
                var managedUser = ps.getUser(null, wh.ManagedBy);
                mwh.ManagedUser = managedUser.firstName;
            }
            mwh.IsLock = wh.IsLock;
            mwh.Status = wh.Status;
            return mwh;

        }

        public List<InvWhEntity> GetInvWhAllList()
        {
            return InvWhBs.GetInvWhAllList(new InvWhEntity { IsActive = 1, Status = Common.WfStatus.WFS30.ToString() });

        }

        public List<InvWhEntity> GetInvWhUnlockAllList()
        {
            return InvWhBs.GetInvWhAllList(new InvWhEntity { IsActive = 1, IsLock = 0, Status = Common.WfStatus.WFS30.ToString() });
        }

        //新增库位、库位属性
        public int? AddInvLoc(string userNo, InvWhLocationEntity loc)
        {
            if (loc == null)
                return 1;
            InvWhLocationExEntity locationEx = new InvWhLocationExEntity();
            locationEx.Id = Guid.NewGuid().ToString();
            locationEx.LocationId = loc.Id;
            locationEx.CreatedBy = userNo;
            locationEx.CreatedDate = DateTime.Now;
            locationEx.UpdatedBy = userNo;
            locationEx.UpdatedDate = DateTime.Now;
            locationEx.IsActive = 1;
            locationEx.Type = (int)InvStoreType.通用;
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Insert(loc, broker);
                    DataAccess.Insert(locationEx, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 2;
                }

            }
        }

        //批量新增库位、库位属性
        public int? AddInvLocs(string userNo, List<InvWhLocationEntity> locs)
        {
            if (locs == null)
                return 1;
            List<InvWhLocationExEntity> locationExs = new List<InvWhLocationExEntity>();
            foreach (var loc in locs)
            {
                InvWhLocationExEntity locationEx = new InvWhLocationExEntity();
                locationEx.Id = Guid.NewGuid().ToString();
                locationEx.LocationId = loc.Id;
                locationEx.CreatedBy = userNo;
                locationEx.CreatedDate = DateTime.Now;
                locationEx.UpdatedBy = userNo;
                locationEx.UpdatedDate = DateTime.Now;
                locationEx.IsActive = 1;
                locationEx.Type = (int)InvStoreType.通用;
                locationExs.Add(locationEx);
            }
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Insert(locs, broker);
                    DataAccess.Insert(locationExs, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 2;
                }

            }
        }

        public int? UpdateInvLoc(InvWhLocationEntity loc)
        {
            if (loc == null)
                return 1;
            if (InvWhLocationBs.UpdateInvWhLocation(loc))
                return null;
            else return -1;
        }

        public int? DelInvLoc(InvWhLocationEntity loc)
        {
            if (loc == null)
                return 1;
            var locEx = DataAccess.SelectSingle(new InvWhLocationExEntity { Id = loc.Id });
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    if (locEx != null)
                        DataAccess.Delete(locEx, broker);
                    DataAccess.Delete(loc, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return -1;
                }
            }
        }

        public int? SaveInvLoc(string userNo, InvWhLocationEntity loc)
        {
            if (loc == null)
                return 1;
            var cur = InvWhLocationBs.GetInvWhLocation(new InvWhLocationEntity { Id = loc.Id });
            if (cur == null)
            {
                InvWhLocationExEntity locationEx = new InvWhLocationExEntity();
                locationEx.Id = Guid.NewGuid().ToString();
                locationEx.LocationId = loc.Id;
                locationEx.CreatedBy = userNo;
                locationEx.CreatedDate = DateTime.Now;
                locationEx.UpdatedBy = userNo;
                locationEx.UpdatedDate = DateTime.Now;
                locationEx.IsActive = 1;
                locationEx.Type = (int)InvStoreType.通用;

                using (DataAccessBroker broker = DataAccessFactory.Instance())
                {
                    try
                    {
                        broker.BeginTransaction();
                        DataAccess.Insert(loc, broker);
                        DataAccess.Insert(locationEx, broker);
                        broker.Commit();
                        return null;
                    }
                    catch (Exception ex)
                    {
                        broker.RollBack();
                        return -1;
                    }

                }
            }
            else
            {
                if (InvWhLocationBs.UpdateInvWhLocation(loc))
                    return null;
                else return -1;
            }
        }

        public List<InvWhLocationEntity> GetInvLocsByWhId(string whId)
        {
            if (string.IsNullOrEmpty(whId))
                return null;
            return InvWhLocationBs.GetWhLocsByWhId(whId);
        }

        public DataSet GetInvLocsDsByWhId(string whId)
        {
            if (string.IsNullOrEmpty(whId))
                return null;
            string sql = @"SELECT loc.*,ex.TYPE,prd.PRODUCT_NAME,null as RELATED_NO,stg.CURRENT_QTY
FROM INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_STG stg on ex.LOCATION_ID=stg.LOCATION_ID and ex.PRODUCT_ID=stg.PRODUCT_ID
left join MST_PRODUCT prd on stg.PRODUCT_ID=prd.PRODUCT_ID
where (ex.TYPE=10 or ex.TYPE=20) and loc.WH_ID='{0}'
union
SELECT loc.*,ex.TYPE,null as PRODUCT_NAME,po.PO_NO as RELATED_NO,null as CURRENT_QTY
FROM INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join PROD_PLAN_ORDER po on ex.RELATED_ID=po.ID
where ex.TYPE=30 and loc.WH_ID='{0}'
union
SELECT loc.*,30 as TYPE,p.PRODUCT_NAME,w.WO_NO as RELATED_NO,stg.CURRENT_QTY
FROM INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join PROD_WO_TASK t on ex.RELATED_ID=t.ID
left join PROD_WO w on t.WO_ID=w.ID
left join MST_PRODUCT p on w.PRODUCT_ID=p.PRODUCT_ID
left join INV_STG stg on ex.ID=stg.LOCATION_ID and ex.PRODUCT_ID=stg.PRODUCT_ID
where ex.TYPE=40 and loc.WH_ID='{0}'";
            sql = string.Format(sql, whId);
            return InvWhLocationBs.GetWhLocsBySql(sql);
        }

        //xu
        public DataSet GetInvLocsDsByCodition(string condition)
        {
            try
            {
                return InvWhLocationBs.GetInvLocsDsByCodition(condition);
            }
            catch (Exception ex)
            {
                MyDebug.write(ex.Message);
                return null;
            }
        }
        #endregion


        #region //入库,申请

        public InvMaintainIApp AddInvIApp(InvMaintainIApp miapp, DataSet iappis)
        {
            if (miapp == null)
                return null;
            if (iappis == null)
                return null;
            if (iappis.Tables[0].Rows.Count == 0)
                return null;
            var iapp = new InvIappEntity();
            iapp.Id = miapp.Id;
            iapp.CreatedBy = miapp.CreatedBy;
            iapp.CreatedDate = DateTime.Now;
            iapp.UpdatedBy = miapp.UpdatedBy;
            iapp.UpdatedDate = DateTime.Now;
            iapp.IsActive = miapp.IsActive;
            iapp.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvInAppOrder");
            iapp.Type = miapp.Type;
            iapp.RelatedId = miapp.RelatedId;
            iapp.Remark = miapp.Remark;
            iapp.Status = Common.WfStatus.WFS10.ToString();

            miapp.AppNo = iapp.AppNo;
            miapp.CreatedDate = DateTime.Now;
            miapp.UpdatedDate = DateTime.Now;
            miapp.Status = iapp.Status;
            var iappi_list = new List<InvIappiEntity>();
            foreach (DataRow dr in iappis.Tables[0].Rows)
            {
                var iappi = new InvIappiEntity();
                iappi.Id = dr["ID"].ToString();
                iappi.IoAppId = miapp.Id.ToString();
                iappi.ProductId = dr["PRODUCT_ID"].ToString();
                iappi.Qty = Convert.ToDecimal(dr["QTY"].ToString());
                iappi_list.Add(iappi);
            }
            if (InvIappBs.AddInvIapp(iapp, iappi_list))
                return miapp;
            else return null;

        }

        public InvMaintainIApp UpdateInvIApp(InvMaintainIApp miapp)
        {
            if (miapp == null)
                return null;
            var iapp = InvIappBs.GetInvIapp(new InvIappEntity { Id = miapp.Id });
            if (iapp == null)
                return null;
            iapp.Id = miapp.Id;
            iapp.UpdatedBy = miapp.UpdatedBy;
            iapp.UpdatedDate = DateTime.Now;
            iapp.IsActive = miapp.IsActive;
            iapp.AppNo = miapp.AppNo;
            iapp.Type = miapp.Type;
            iapp.RelatedId = miapp.RelatedId;
            iapp.Remark = miapp.Remark;
            iapp.Status = miapp.Status;

            miapp.UpdatedDate = DateTime.Now;
            miapp.Status = iapp.Status;
            if (InvIappBs.UpdateInvIapp(iapp))
                return miapp;
            else return null;
        }

        public int? DelInvIApp(InvMaintainIApp miapp)
        {
            if (miapp == null)
                return 1;
            var iapp = InvIappBs.GetInvIapp(new InvIappEntity { Id = miapp.Id });
            if (InvIappBs.DeleteInvIapp(iapp))
                return null;
            else return -1;
        }

        public int? DelInvIAppEntity(InvIappEntity iapp)
        {
            if (iapp == null)
                return 1;
            if (InvIappBs.DeleteInvIapp(iapp))
                return null;
            else return -1;
        }

        public int? DelInvIAppiEntity(InvIappiEntity iappi)
        {
            if (iappi == null)
                return 1;
            if (InvIappiBs.DeleteInvIappi(iappi))
                return null;
            else return -1;
        }

        //public int? SaveInvIAppi(InvIappiEntity iappi)
        //{
        //    if (iappi == null)
        //        return 1;
        //    var cur = InvIappiBs.GetInvIappi(new InvIappiEntity { Id = iappi.Id });
        //    if (cur == null)
        //    {
        //        if (InvIappiBs.InsertInvIappi(iappi))
        //            return null;
        //        else return -1;
        //    }
        //    else
        //    {
        //        cur.ProductId = iappi.ProductId;
        //        cur.Qty = iappi.Qty;
        //        if (InvIappiBs.UpdateInvIappi(cur))
        //            return null;
        //        else return -1;
        //    }

        //}

        //public int? SaveInvIAppis(DataSet iappis)
        //{
        //    if (iappis == null)
        //        return 1;
        //    if (iappis.Tables[0].Rows.Count == 0)
        //        return 2;
        //    List<InvIappiEntity> updates = new List<InvIappiEntity>();
        //    foreach (DataRow dr in iappis.Tables[0].Rows)
        //    {
        //        if (dr.RowState == DataRowState.Modified)
        //        {
        //            var appi = new InvIappiEntity(dr);
        //            updates.Add(appi);
        //        }
        //    }
        //    if (InvIappiBs.UpdateInvIappi(updates))
        //        return null;
        //    else return -1;
        //}

        public int? SaveInvIApp(InvIappSaveParam param)
        {
            if (param == null)
                return 1;
            if (param.app == null)
                return 2;
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvIappEntity cur = DataAccess.SelectSingle<InvIappEntity>(new InvIappEntity { Id = param.app.Id });
                    if (cur == null)//新增
                    {
                        param.app.CreatedDate = DateTime.Now;
                        param.app.UpdatedDate = DateTime.Now;
                        param.app.CreatedBy = param.curUserNo;
                        param.app.UpdatedBy = param.curUserNo;
                        param.app.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvInAppOrder");
                        foreach (var item in param.addItems)
                        {
                            item.IoAppId = param.app.Id;
                        }

                        Mapper.CreateMap<InvMaintainIApp, InvIappEntity>();
                        InvIappEntity app = AutoMapper.Mapper.Map<InvMaintainIApp, InvIappEntity>(param.app);

                        List<InvIappiEntity> items = new List<InvIappiEntity>();
                        foreach (var addItemDto in param.addItems)
                        {
                            Mapper.CreateMap<InvIAppItemDto, InvIappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvIAppItemDto, InvIappiEntity>(addItemDto);
                            items.Add(item);
                        }

                        broker.BeginTransaction();
                        DataAccess.Insert(app, broker);
                        DataAccess.Insert(items, broker);
                        broker.Commit();
                        return null;
                    }
                    else//修改
                    {
                        param.app.UpdatedDate = DateTime.Now;
                        param.app.UpdatedBy = param.curUserNo;
                        foreach (var item in param.addItems)
                        {
                            item.IoAppId = param.app.Id;
                        }

                        Mapper.CreateMap<InvMaintainIApp, InvIappEntity>();
                        InvIappEntity app = AutoMapper.Mapper.Map<InvMaintainIApp, InvIappEntity>(param.app);

                        List<InvIappiEntity> delItems = new List<InvIappiEntity>();
                        foreach (var delItemDto in param.delItems)
                        {
                            Mapper.CreateMap<InvIAppItemDto, InvIappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvIAppItemDto, InvIappiEntity>(delItemDto);
                            delItems.Add(item);
                        }

                        List<InvIappiEntity> updatedItems = new List<InvIappiEntity>();
                        foreach (var updatedItemDto in param.updatedItems)
                        {
                            Mapper.CreateMap<InvIAppItemDto, InvIappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvIAppItemDto, InvIappiEntity>(updatedItemDto);
                            updatedItems.Add(item);
                        }

                        List<InvIappiEntity> addItems = new List<InvIappiEntity>();
                        foreach (var addItemDto in param.addItems)
                        {
                            Mapper.CreateMap<InvIAppItemDto, InvIappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvIAppItemDto, InvIappiEntity>(addItemDto);
                            addItems.Add(item);
                        }

                        broker.BeginTransaction();
                        DataAccess.Update(app, broker);
                        DataAccess.Delete(delItems, broker);
                        DataAccess.Update(updatedItems, broker);
                        DataAccess.Insert(addItems, broker);
                        broker.Commit();
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 3;
                }
            }
        }

        public InvMaintainIApp GetInvMaintainIAppByKey(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            var app = InvIappBs.GetInvIapp(new InvIappEntity { Id = appId });
            if (app == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            var mapp = new InvMaintainIApp();
            mapp.Id = app.Id;
            mapp.CreatedBy = app.CreatedBy;
            if (!string.IsNullOrEmpty(app.CreatedBy))
            {
                var createdUser = ps.getUser(null, app.CreatedBy);
                mapp.CreatedUser = createdUser.firstName;
            }
            mapp.CreatedDate = app.CreatedDate;
            mapp.UpdatedBy = app.UpdatedBy;
            if (!string.IsNullOrEmpty(app.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, app.UpdatedBy);
                mapp.UpdatedUser = updatedUser.firstName;
            }
            mapp.UpdatedDate = app.UpdatedDate;
            mapp.IsActive = app.IsActive;
            mapp.AppNo = app.AppNo;
            mapp.Type = app.Type;
            mapp.RelatedId = app.RelatedId;
            if (!string.IsNullOrEmpty(app.RelatedId))
            {
                switch (app.Type)
                {
                    case 10:
                        //工单入库
                        //var wo = ProdWoBs.GetProdWo(new ProdWoEntity { Id = app.RelatedId });
                        //if (wo == null)
                        //    return null;
                        mapp.RelatedNo = app.RelatedId;
                        break;
                    case 20:
                        var po = PurPoBs.GetPurPo(new PurPoEntity { Id = app.RelatedId });
                        if (po == null)
                            return null;
                        mapp.RelatedNo = po.PoNo;
                        break;
                    case 30:

                        break;
                    case 40:

                        break;
                    case 50:
                        mapp.RelatedNo = app.RelatedId;
                        break;
                    default:
                        return null;
                }
            }
            mapp.Remark = app.Remark;
            mapp.Status = app.Status;
            return mapp;

        }

        public DataSet GetInvIAppAllDsByCondition(InvIAppQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.CreatedBy))
            {
                condition += " and app.CREATED_BY='" + con.CreatedBy + "'";
            }
            else if (!string.IsNullOrEmpty(con.CreatedUser))
            {
                condition += " and u1.firstName like '%" + con.CreatedUser + "%'";
            }
            if (con.IsActive != null)
            {
                condition += " and app.IS_ACTIVE=" + con.IsActive;
            }
            if (!string.IsNullOrEmpty(con.AppNo))
            {
                condition += " and app.APP_NO='" + con.AppNo + "'";
            }
            if (con.Type != null)
            {
                condition += " and app.TYPE=" + con.Type;
            }
            if (!string.IsNullOrEmpty(con.RelatedId))
            {
                condition += " and app.RELATED_ID='" + con.RelatedId + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and app.STATUS='" + con.Status + "'";
            }

            return InvIappBs.GetAllDsByCondition(pageIndex, pageSize, condition);
        }

        public DataSet GetInvIAppiAllDsByAppId(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            return InvIappiBs.GetAllDsByAppId(appId);
        }

        public List<InvIAppItemDto> GetInvIAppItemsDtoByAppId(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            List<InvIappiEntity> items = DataAccess.Select<InvIappiEntity>(new InvIappiEntity { IoAppId = appId });
            if (items == null)
                return null;
            List<InvIAppItemDto> itemsDto = new List<InvIAppItemDto>();
            foreach (var item in items)
            {
                Mapper.CreateMap<InvIappiEntity, InvIAppItemDto>();
                var itemDto = AutoMapper.Mapper.Map<InvIappiEntity, InvIAppItemDto>(item);
                var material = DataAccess.SelectSingle<MstProductEntity>(new MstProductEntity { ProductId = item.ProductId });
                if (material != null)
                {
                    itemDto.ProductName = material.ProductName;
                    itemDto.ProductCode = material.ProductCode;
                    itemDto.Unit = material.Unit;
                }
                itemsDto.Add(itemDto);
            }
            return itemsDto;

        }

        public InvMaintainIo InvIappToIo(InvMaintainIApp iapp, DataSet iappis)
        {
            if (iapp == null)
                return null;
            if (iappis == null)
                return null;
            if (iappis.Tables[0].Rows.Count == 0)
                return null;
            var io = new InvIoEntity();
            io.Id = Guid.NewGuid().ToString();
            io.CreatedBy = iapp.UpdatedBy;
            io.CreatedDate = DateTime.Now;
            io.UpdatedBy = iapp.UpdatedBy;
            io.UpdatedDate = DateTime.Now;
            io.IsActive = 1;
            io.IoNo = MstCodeRuleBs.GetCurrentOrderCode("InvInOrder");
            io.Type = iapp.Type;
            io.RelatedId = iapp.RelatedId;
            io.Remark = iapp.Remark;
            io.Status = Common.WfStatus.WFS10.ToString();

            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));
            var mio = new InvMaintainIo();
            mio.Id = io.Id;
            mio.CreatedBy = iapp.UpdatedBy;
            mio.CreatedDate = io.UpdatedDate;
            if (!string.IsNullOrEmpty(iapp.UpdatedBy))
            {
                var createdUser = ps.getUser(null, iapp.UpdatedBy);
                mio.CreatedUser = createdUser.firstName;
            }
            mio.UpdatedBy = iapp.UpdatedBy;
            mio.UpdatedDate = io.UpdatedDate;
            if (!string.IsNullOrEmpty(iapp.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, iapp.UpdatedBy);
                mio.UpdatedUser = updatedUser.firstName;
            }
            mio.IsActive = 1;
            mio.IoNo = io.IoNo;
            mio.RelatedId = iapp.RelatedId;
            mio.Remark = iapp.Remark;
            mio.Status = io.Status;

            List<InvIoiEntity> iois = new List<InvIoiEntity>();
            foreach (DataRow dr in iappis.Tables[0].Rows)
            {
                var ioi = new InvIoiEntity();
                ioi.Id = Guid.NewGuid().ToString();
                ioi.IoId = io.Id;
                ioi.ProductId = dr["PRODUCT_ID"].ToString();
                ioi.Qty = Convert.ToDecimal(dr["QTY"]);
                iois.Add(ioi);
            }
            if (InvIoBs.AddInvIo(io, iois))
                return mio;
            else return null;

        }


        public InvMaintainIo AddInvIo(InvMaintainIo mio, List<InvMaintainIoi> iois)
        {
            if (mio == null)
                return null;
            if (iois == null)
                return null;
            if (iois.Count == 0)
                return null;
            var io = new InvIoEntity();
            io.Id = mio.Id;
            io.CreatedBy = mio.CreatedBy;
            io.CreatedDate = DateTime.Now;
            io.UpdatedBy = mio.UpdatedBy;
            io.UpdatedDate = DateTime.Now;
            io.IsActive = mio.IsActive;
            io.WhId = mio.WhId;
            io.IoNo = MstCodeRuleBs.GetCurrentOrderCode("InvInOrder");
            io.Type = mio.Type;
            io.RelatedId = mio.RelatedId;
            io.Remark = mio.Remark;
            io.Status = Common.WfStatus.WFS10.ToString();

            mio.IoNo = io.IoNo;
            mio.CreatedDate = DateTime.Now;
            mio.UpdatedDate = DateTime.Now;
            mio.Status = io.Status;
            var ioi_list = new List<InvIoiEntity>();
            foreach (var i in iois)
            {
                var ioi = new InvIoiEntity();
                ioi.Id = i.Id;
                ioi.IoId = mio.Id.ToString();
                ioi.ProductId = i.ProductId;
                ioi.Qty = Convert.ToDecimal(i.Qty);
                ioi.Remark = i.Remark;
                ioi.LocationId = i.LocationId;
                ioi_list.Add(ioi);
            }
            if (InvIoBs.AddInvIo(io, ioi_list))
                return mio;
            else return null;

        }

        public InvMaintainIo UpdateInvIo(InvMaintainIo mio)
        {
            if (mio == null)
                return null;
            var io = InvIoBs.GetInvIo(new InvIoEntity { Id = mio.Id });
            if (io == null)
                return null;
            io.UpdatedBy = mio.UpdatedBy;
            io.UpdatedDate = DateTime.Now;
            io.IsActive = mio.IsActive;
            io.WhId = mio.WhId;
            io.Type = mio.Type;
            io.Remark = mio.Remark;
            mio.UpdatedDate = io.UpdatedDate;
            mio.Status = io.Status;
            if (InvIoBs.UpdateInvIo(io))
                return mio;
            else return null;
        }

        public int? DelInvIo(InvMaintainIo mio)
        {
            if (mio == null)
                return 1;
            var io = InvIoBs.GetInvIo(new InvIoEntity { Id = mio.Id });
            if (io == null)
                return 2;
            if (InvIoBs.DeleteInvIo(io))
                return null;
            else return -1;
        }

        public int? DelInvIoEntity(InvIoEntity io)
        {
            if (io == null)
                return 1;
            if (InvIoBs.DeleteInvIo(io))
                return null;
            else return -1;
        }

        public int? DelInvIoiEntity(InvIoiEntity ioi)
        {
            if (ioi == null)
                return 1;
            if (InvIoiBs.DeleteInvIoi(ioi))
                return null;
            else return -1;
        }

        public int? SaveInvIoisDs(DataSet iois)
        {
            if (iois == null)
                return 1;
            if (iois.Tables[0].Rows.Count == 0)
                return 2;
            List<InvIoiEntity> iois_list = new List<InvIoiEntity>();
            foreach (DataRow dr in iois.Tables[0].Rows)
            {
                if (dr.RowState == DataRowState.Modified)
                {
                    var ioi = new InvIoiEntity();
                    ioi.Id = dr["ID"].ToString();
                    ioi.IoId = dr["IO_ID"].ToString();
                    ioi.ProductId = dr["PRODUCT_ID"].ToString();
                    ioi.Qty = Convert.ToDecimal(dr["QTY"]);
                    ioi.Remark = dr["REMARK"].ToString();
                    ioi.LocationId = dr["LOCATION_ID"].ToString();
                    iois_list.Add(ioi);
                }
            }
            if (InvIoiBs.UpdateInvIoi(iois_list))
                return null;
            else return -1;

        }

        public int? SaveInvIoisList(List<InvMaintainIoi> iois)
        {
            if (iois == null)
                return 1;
            if (iois.Count == 0)
                return 2;
            List<InvIoiEntity> iois_list = new List<InvIoiEntity>();
            foreach (InvMaintainIoi mioi in iois)
            {
                var ioi = new InvIoiEntity();
                ioi.Id = mioi.Id;
                ioi.IoId = mioi.IoId;
                ioi.ProductId = mioi.ProductId;
                ioi.Qty = mioi.Qty;
                ioi.Remark = mioi.Remark;
                ioi.LocationId = mioi.LocationId;
                ioi.Type = mioi.Type;
                iois_list.Add(ioi);
            }
            if (InvIoiBs.UpdateInvIoi(iois_list))
                return null;
            else return -1;
        }

        public DataSet GetInvIoiAllDsByIoId(string ioId)
        {
            if (string.IsNullOrEmpty(ioId))
                return null;
            string sql = @"select ioi.*,loc.STAND,loc.LOCATION,loc.VOLUME,loc.AREA,loc.IS_SINGLE 
from INV_IOI ioi
left join INV_WH_LOCATION loc on ioi.LOCATION_ID=loc.ID
where ioi.IO_ID='{0}'";
            sql = string.Format(sql, ioId);
            return InvWhLocationBs.GetWhLocsBySql(sql);
        }

        public InvMaintainIo GetInvMaintainIoByKey(string ioId)
        {
            if (string.IsNullOrEmpty(ioId))
                return null;
            var io = InvIoBs.GetInvIo(new InvIoEntity { Id = ioId });
            if (io == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            var mio = new InvMaintainIo();
            mio.Id = io.Id;
            mio.CreatedBy = io.CreatedBy;
            if (!string.IsNullOrEmpty(io.CreatedBy))
            {
                var createdUser = ps.getUser(null, io.CreatedBy);
                mio.CreatedUser = createdUser.firstName;
            }
            mio.CreatedDate = io.CreatedDate;
            mio.UpdatedBy = io.UpdatedBy;
            if (!string.IsNullOrEmpty(io.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, io.UpdatedBy);
                mio.UpdatedUser = updatedUser.firstName;
            }
            mio.UpdatedDate = io.UpdatedDate;
            mio.IsActive = io.IsActive;
            mio.WhId = io.WhId;
            mio.IoNo = io.IoNo;
            mio.Type = io.Type;
            mio.RelatedId = io.RelatedId;
            if (!string.IsNullOrEmpty(io.RelatedId))
            {
                switch (io.Type)
                {
                    case 10://工单入库
                        //var wo = ProdWoBs.GetProdWo(new ProdWoEntity { Id = io.RelatedId });
                        //if (wo == null)
                        //    return null;
                        mio.RelatedNo = io.RelatedId;
                        break;
                    case 20:
                        var po = PurPoBs.GetPurPo(new PurPoEntity { Id = io.RelatedId });
                        if (po == null)
                            return null;
                        mio.RelatedNo = po.PoNo;
                        break;
                    case 30:

                        break;
                    case 40:

                        break;
                    case 50:
                        mio.RelatedNo = io.RelatedId;
                        break;
                    default:
                        return null;
                }
            }
            mio.Remark = io.Remark;
            mio.Status = io.Status;
            return mio;
        }

        public DataSet GetInvIoAllDsByCondition(InvIoQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.CreatedBy))
            {
                condition += " and io.CREATED_BY='" + con.CreatedBy + "'";
            }
            else if (!string.IsNullOrEmpty(con.CreatedUser))
            {
                condition += " and u1.firstName like '%" + con.CreatedUser + "%'";
            }
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and io.WH_ID='" + con.WhId + "'";
            }
            if (con.IsActive != null)
            {
                condition += " and io.IS_ACTIVE=" + con.IsActive;
            }
            if (!string.IsNullOrEmpty(con.IoNo))
            {
                condition += " and io.IO_NO='" + con.IoNo + "'";
            }
            if (con.Type != null)
            {
                condition += " and io.TYPE=" + con.Type;
            }
            if (!string.IsNullOrEmpty(con.RelatedId))
            {
                condition += " and io.RELATED_ID='" + con.RelatedId + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and io.STATUS='" + con.Status + "'";
            }

            return InvIoBs.GetAllDsByCondition(pageIndex, pageSize, condition);
        }

        public List<InvMaintainIoi> GetInvIoiAllListByIoId(string ioId)
        {
            if (string.IsNullOrEmpty(ioId))
                return null;
            string sql = @"Select ioi.*,mp.PRODUCT_NAME,mp.PRODUCT_CODE,loc.STAND,loc.LOCATION,loc.VOLUME,loc.AREA,loc.IS_SINGLE 
from INV_IOI ioi
left join MST_PRODUCT mp on ioi.PRODUCT_ID=mp.PRODUCT_ID
left join INV_WH_LOCATION loc on ioi.LOCATION_ID=loc.ID
where ioi.IO_ID='{0}'";
            sql = string.Format(sql, ioId);
            DataSet ds = InvIoBs.GetAllDsBySql(sql);
            if (ds == null)
                return null;
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            var results = new List<InvMaintainIoi>();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                var r = new InvMaintainIoi();
                r.Id = dr["ID"].ToString();
                r.IoId = dr["IO_ID"].ToString();
                r.ProductId = dr["PRODUCT_ID"].ToString();
                r.ProductName = dr["PRODUCT_NAME"].ToString();
                r.ProductCode = dr["PRODUCT_CODE"].ToString();
                r.Qty = Convert.ToDecimal(dr["QTY"].ToString());
                r.Remark = dr["REMARK"].ToString();
                r.LocationId = dr["LOCATION_ID"].ToString();
                if (dr["TYPE"] == null || dr["TYPE"] == DBNull.Value)
                {
                    r.Type = 0;
                }
                else
                {
                    r.Type = (int)dr["TYPE"];
                }
                r.Stand = dr["STAND"].ToString();
                r.LocationNo = dr["LOCATION"].ToString();
                if (dr["VOLUME"].ToString() != "")
                    r.Volume = Convert.ToDecimal(dr["VOLUME"].ToString());
                if (dr["Area"].ToString() != "")
                    r.Area = Convert.ToDecimal(dr["Area"].ToString());
                if (dr["IS_SINGLE"].ToString() != "")
                    r.IsSingle = Convert.ToInt32(dr["IS_SINGLE"].ToString());
                results.Add(r);
            }
            return results;
        }


        //xu
        public InvProdInventoryEntity AddProdInventory(InvProdInventoryEntity prodInventory, List<InvProdInventoryItemEntity> invItems)
        {
            try
            {

                return InvProdInventoryBs.AddProdInventory(prodInventory, invItems);

            }
            catch (Exception ex)
            {
                MyDebug.write("AddProdInventory:" + ex.Message);
                return null;
            }
        }

        public InvProdInventoryEntity UpdateProdInventory(InvProdInventoryEntity prodInventory, List<InvProdInventoryItemEntity> invItems)
        {
            try
            {

                return InvProdInventoryBs.UpdateProdInventory(prodInventory, invItems);

            }
            catch (Exception ex)
            {
                MyDebug.write("UpdateProdInventory:" + ex.Message);
                return null;
            }
        }

        public InvProdInventoryEntity DeleteProdInventory(InvProdInventoryEntity prodInventory)
        {
            try
            {
                return InvProdInventoryBs.DeleteProdInventory(prodInventory);
            }
            catch (Exception ex)
            {
                MyDebug.write("DeleteProdInventory:" + ex.Message);
                return null;
            }
        }

        public InvProdInventoryEntity GetProdInventory(InvProdInventoryEntity prodInventory)
        {
            return InvProdInventoryBs.GetProdInventory(prodInventory);
        }

        public List<InvProdInventoryItemEntity> GetProdInventoryItems(InvProdInventoryEntity prodInventory)
        {
            return InvProdInventoryBs.GetProdInventoryItems(prodInventory);
        }

        public List<InvProdInventoryEntity> GetProdInventoryList(InvProdInventoryEntity prodInventory)
        {
            return InvProdInventoryBs.GetProdInventoryList(prodInventory);
        }

        //工单入库的最大可入库数
        public decimal GetAllowInventoryMaxQty(string woNo, string transNo, string technicItemId, string curWorkgroupNo)
        {
            try
            {
                return InvProdInventoryBs.GetAllowInventoryMaxQty(woNo, transNo, technicItemId, curWorkgroupNo);
            }
            catch (Exception ex)
            {
                return 0;
            }
        }

        #endregion

        #region 自动分配库位
        /// <summary>
        /// 查询满足库位存储类型、库位库存空、空间足够的库位
        /// 库位分配规则：按仓库与物料类别绑定，级别越高，该仓库及库位有限选取
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="type">库位库存类型</param>
        /// <param name="volume"></param>
        /// <param name="area"></param>
        /// <param name="ex">排除的库位ID</param>
        /// <returns></returns>
        private string GetWhLocationForAutoAssign(string productId, int type, decimal qty, decimal volume, decimal area, ArrayList ex)
        {
            string sql = @"select top 1 * 
from INV_WH_ITEM_EX
where PRODUCT_TYPE_ID=(
select t.PARENT_TYPE_ID as PRODUCT_TYPE_ID 
from MST_PRODUCT p
left join MST_PRODUCT_TYPE t on p.PRODUCT_TYPE_ID=t.PRODUCT_TYPE_ID
where p.PRODUCT_ID='{0}')
order by LEVEL";
            sql = string.Format(sql, productId);
            DataSet ds = InvWhItemExBs.GetAllDsBySql(sql);
            if (ds.Tables[0].Rows.Count == 0)
            {
                return null;
            }
            else
            {
                sql = @"select loc.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.ID
left join INV_STG stg on ex.ID=stg.LOCATION_ID
where loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE='{1}' and stg.ID is null";
                if (volume != 0 && area != 0)
                    sql += " and loc.VOLUME<={2} and loc.ARER<={3}";
                if (ex.Count > 0)
                {
                    sql += " and loc.ID not in (";
                    for (int i = 0; i < ex.Count; i++)
                    {
                        sql += "'" + ex[i] + "',";
                    }
                    sql = sql.Substring(0, sql.Length - 1) + ")";
                }
                sql = string.Format(sql, ds.Tables[0].Rows[0]["WH_ID"].ToString(), type, volume * qty, area * qty);
                DataSet result = InvWhLocationBs.GetWhLocsBySql(sql);
                if (result.Tables[0].Rows.Count == 0)
                    return null;
                else return result.Tables[0].Rows[0]["ID"].ToString();
            }
        }

        /// <summary>
        /// 按订单存储类型，查询满足库位存储类型库位
        /// 库位分配规则：按仓库与物料类别绑定，级别越高，该仓库及库位有限选取
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="type">库位库存类型</param>
        /// <param name="volume"></param>
        /// <param name="area"></param>
        /// <param name="ex">排除的库位ID</param>
        /// <returns></returns>
        private string GetWhLocationForAutoAssign(string productId, int type, ArrayList ex)
        {
            string sql = @"select top 1 * 
from INV_WH_ITEM_EX
where PRODUCT_TYPE_ID=(
select t.PARENT_TYPE_ID as PRODUCT_TYPE_ID 
from MST_PRODUCT p
left join MST_PRODUCT_TYPE t on p.PRODUCT_TYPE_ID=t.PRODUCT_TYPE_ID
where p.PRODUCT_ID='{0}')
order by LEVEL";
            sql = string.Format(sql, productId);
            DataSet ds = InvWhItemExBs.GetAllDsBySql(sql);
            if (ds.Tables[0].Rows.Count == 0)
            {
                return null;
            }
            else
            {
                sql = @"select loc.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.ID
where loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE='{1}' and (ex.RELATED_ID is null or ex.RELATED_ID='')";
                if (ex.Count > 0)
                {
                    sql += " and loc.ID not in (";
                    for (int i = 0; i < ex.Count; i++)
                    {
                        sql += "'" + ex[i] + "',";
                    }
                    sql = sql.Substring(0, sql.Length - 1) + ")";
                }
                sql = string.Format(sql, ds.Tables[0].Rows[0]["WH_ID"].ToString(), type);
                DataSet result = InvWhLocationBs.GetWhLocsBySql(sql);
                if (result.Tables[0].Rows.Count == 0)
                    return null;
                else return result.Tables[0].Rows[0]["ID"].ToString();
            }
        }

        /// <summary>
        /// 根据物料数量，检查不存在存储信息的库位空间
        /// </summary>
        /// <param name="locationId"></param>
        /// <param name="material"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        private bool CheckLocationSpace(string locationId, MstProductEntity material, decimal qty)
        {
            if (material.Volume == 0 || material.Arer == 0)
                return true;
            InvWhLocationEntity location = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
            if (location == null)
                return false;
            if (material.Volume * qty <= location.Volume)
                return true;
            else return false;
        }

        //根据库位、物料，检查库位仓储的空间
        private bool CheckStorageSpace(string locationId, MstProductEntity material, decimal qty)
        {
            InvStgEntity stg = DataAccess.SelectSingle<InvStgEntity>(new InvStgEntity { LocationId = locationId, ProductId = material.ProductId });
            if (stg == null)
            {
                return CheckLocationSpace(locationId, material, qty);
            }
            if (stg.IsFull == 1)
                return false;
            else return true;
        }

        //根据物料，查询闲置的通用类型库位
        private string GetWhLocationByFreeCommonType(string userNo, string whId, MstProductEntity material, decimal qty, string invIoId)
        {
            string sql = @"select ex.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE={1}
and (ex.PRODUCT_ID='' or ex.PRODUCT_ID is null)
order by loc.STAND,loc.LOCATION";
            sql = string.Format(sql, whId, (int)InvStoreType.通用);
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                string locId = dr["LOCATION_ID"].ToString();
                if (CheckLocationSpace(locId, material, qty))
                {
                    InvWhLocationExEntity ex = new InvWhLocationExEntity(dr);
                    ex.UpdatedDate = DateTime.Now;
                    ex.UpdatedBy = userNo;
                    ex.IsActive = 1;
                    ex.Type = (int)InvStoreType.通用;
                    ex.ProductId = material.ProductId;
                    InvLocationExHisEntity his = new InvLocationExHisEntity();
                    his.Id = Guid.NewGuid().ToString();
                    his.LocationExId = ex.Id;
                    his.InvIoId = invIoId;
                    his.LocationId = ex.LocationId;
                    his.MaterialId = material.ProductId;
                    his.HisExType = (int)InvStoreType.通用;
                    his.HisMaterialId = null;
                    his.Type = (int)LocationExHisType.Update;
                    DataAccess.Update(ex);
                    DataAccess.Insert(his);
                    return ex.LocationId;
                }
                else
                {
                    continue;
                }
            }
            return null;
        }

        //根据物料，查询闲置的通用类型库位，更新为物料绑定类型
        private string GetWhLocationByFreeBindType(string userNo, string whId, MstProductEntity material, decimal qty, string invIoId)
        {
            string sql = @"select ex.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE='{1}' 
and (ex.PRODUCT_ID='' or ex.PRODUCT_ID is null)
order by loc.STAND,loc.LOCATION";
            sql = string.Format(sql, whId, (int)InvStoreType.通用);
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                string locId = dr["LOCATION_ID"].ToString();
                if (CheckLocationSpace(locId, material, qty))
                {
                    InvWhLocationExEntity ex = new InvWhLocationExEntity(dr);
                    ex.UpdatedDate = DateTime.Now;
                    ex.UpdatedBy = userNo;
                    ex.IsActive = 1;
                    ex.Type = (int)InvStoreType.物料绑定;
                    ex.ProductId = material.ProductId;
                    InvLocationExHisEntity his = new InvLocationExHisEntity();
                    his.Id = Guid.NewGuid().ToString();
                    his.LocationExId = ex.Id;
                    his.InvIoId = invIoId;
                    his.LocationId = ex.LocationId;
                    his.MaterialId = material.ProductId;
                    his.HisExType = (int)InvStoreType.通用;
                    his.HisMaterialId = null;
                    his.Type = (int)LocationExHisType.Update;
                    DataAccess.Update(ex);
                    DataAccess.Insert(his);
                    return ex.LocationId;
                }
                else
                {
                    continue;
                }
            }
            return null;
        }

        //根据物料，查询闲置的通用类型库位，更新为生产订单类型
        private string GetWhLocationByFreeSoType(string userNo, string whId, MstProductEntity material, string relatedId, string invIoId)
        {
            string sql = @"select ex.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and ex.TYPE={0} {1} 
and (ex.PRODUCT_ID='' or ex.PRODUCT_ID is null)
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(whId))
            {
                sql = string.Format(sql, (int)InvStoreType.通用, "");
            }
            else
            {
                sql = string.Format(sql, (int)InvStoreType.通用, "and loc.WH_ID='" + whId + "'");
            }
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            InvWhLocationExEntity ex = new InvWhLocationExEntity(ds.Tables[0].Rows[0]);
            ex.UpdatedDate = DateTime.Now;
            ex.UpdatedBy = userNo;
            ex.IsActive = 1;
            ex.Type = (int)InvStoreType.按生产订单;
            ex.ProductId = material.ProductId;
            ex.RelatedId = relatedId;
            InvLocationExHisEntity his = new InvLocationExHisEntity();
            his.Id = Guid.NewGuid().ToString();
            his.LocationExId = ex.Id;
            his.InvIoId = invIoId;
            his.LocationId = ex.LocationId;
            his.MaterialId = material.ProductId;
            his.HisExType = (int)InvStoreType.通用;
            his.HisMaterialId = null;
            his.Type = (int)LocationExHisType.Update;
            DataAccess.Update(ex);
            DataAccess.Insert(his);
            return ex.LocationId;
        }

        //根据物料，查询闲置的通用类型库位，更新为采购到货批次类型
        private string GetWhLocationByFreePcsType(string userNo, string whId, MstProductEntity material, decimal qty,
            string relatedId, string lotNo, string invIoId)
        {
            string sql = @"select ex.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and ex.TYPE='{0}' {1}
and (ex.PRODUCT_ID='' or ex.PRODUCT_ID is null)
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(whId))
            {
                sql = string.Format(sql, (int)InvStoreType.通用, "");
            }
            else
            {
                sql = string.Format(sql, (int)InvStoreType.通用, "and loc.WH_ID='" + whId + "'");
            }
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                string locId = dr["LOCATION_ID"].ToString();
                if (CheckLocationSpace(locId, material, qty))
                {
                    InvWhLocationExEntity ex = new InvWhLocationExEntity(dr);
                    ex.UpdatedDate = DateTime.Now;
                    ex.UpdatedBy = userNo;
                    ex.IsActive = 1;
                    ex.Type = (int)InvStoreType.按采购到货;
                    ex.ProductId = material.ProductId;
                    ex.RelatedId = relatedId;
                    ex.LotNo = lotNo;
                    InvLocationExHisEntity his = new InvLocationExHisEntity();
                    his.Id = Guid.NewGuid().ToString();
                    his.LocationExId = ex.Id;
                    his.InvIoId = invIoId;
                    his.LocationId = ex.Id;
                    his.MaterialId = material.ProductId;
                    his.HisExType = (int)InvStoreType.通用;
                    his.HisMaterialId = null;
                    his.Type = (int)LocationExHisType.Update;
                    DataAccess.Update(ex);
                    DataAccess.Insert(his);
                    return ex.LocationId;
                }
                else continue;
            }
            return null;
        }

        //通用
        /// <param name="userNo"></param>
        /// <param name="warehouseId"></param>
        /// <param name="material"></param>
        /// <param name="qty"></param>
        /// <param name="invIoId"></param>
        /// <returns></returns>
        private string GetWhLocationForCommonStoreType(string userNo, string warehouseId, MstProductEntity material, decimal qty, string invIoId)
        {
            //根据物料类型查询所属仓库
            string sql = @"select top 1 * 
from INV_WH_ITEM_EX
where PRODUCT_TYPE_ID=(
select t.PARENT_TYPE_ID as PRODUCT_TYPE_ID 
from MST_PRODUCT p
left join MST_PRODUCT_TYPE t on p.PRODUCT_TYPE_ID=t.PRODUCT_TYPE_ID
where p.PRODUCT_ID='{0}')
order by LEVEL";
            sql = string.Format(sql, material.ProductId);
            DataSet ds = new System.Data.DataSet();
            string whId = null;
            if (!string.IsNullOrEmpty(warehouseId))
            {
                whId = warehouseId;
            }
            else
            {
                ds = InvWhItemExBs.GetAllDsBySql(sql);
                if (ds.Tables[0].Rows.Count == 0)
                {
                    whId = null;
                }
                else
                {
                    whId = ds.Tables[0].Rows[0]["WH_ID"].ToString();
                }
            }
            //根据所属仓库、物料ID，查询其库位属性
            sql = @"select loc.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE='{1}' and ex.PRODUCT_ID='{2}'
order by loc.STAND,loc.LOCATION";
            sql = string.Format(sql, whId, (int)InvStoreType.通用, material.ProductId);
            ds = DataAccess.SelectDataSet(sql);
            //库位属性表不存在通用类型对应物料
            //从剩余为空且存储空间足够的查询库位
            if (ds.Tables[0].Rows.Count == 0)
            {
                return GetWhLocationByFreeCommonType(userNo, whId, material, qty, invIoId);
            }
            //库位属性表存在物料关系
            //判断是否有库存
            else
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    if (CheckStorageSpace(dr["ID"].ToString(), material, qty))
                        return dr["ID"].ToString();
                    else continue;
                }
                return GetWhLocationByFreeCommonType(userNo, whId, material, qty, invIoId);
            }
        }

        //物料绑定
        private string GetWhLocationForBindStoreType(string userNo, string warehouseId, MstProductEntity material, decimal qty, string invIoId)
        {
            //根据物料类型查询所属仓库
            string sql = @"select top 1 * 
from INV_WH_ITEM_EX
where PRODUCT_TYPE_ID=(
select t.PARENT_TYPE_ID as PRODUCT_TYPE_ID 
from MST_PRODUCT p
left join MST_PRODUCT_TYPE t on p.PRODUCT_TYPE_ID=t.PRODUCT_TYPE_ID
where p.PRODUCT_ID='{0}')
order by LEVEL";
            sql = string.Format(sql, material.ProductId);
            DataSet ds = new System.Data.DataSet();
            string whId = null;
            if (!string.IsNullOrEmpty(warehouseId))
            {
                whId = warehouseId;
            }
            else
            {
                ds = InvWhItemExBs.GetAllDsBySql(sql);
                if (ds.Tables[0].Rows.Count == 0)
                {
                    whId = null;
                }
                else
                {
                    whId = ds.Tables[0].Rows[0]["WH_ID"].ToString();
                }
            }
            //根据所属仓库查询其库位、库位属性
            sql = @"select loc.* 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.ID
left join INV_WH wh on loc.WH_ID=wh.ID
where wh.IS_ACTIVE=1 and wh.IS_LOCK=0 and loc.IS_ACTIVE=1 and loc.WH_ID='{0}' and ex.TYPE='{1}' and ex.PRODUCT_ID='{2}'
order by loc.STAND,loc.LOCATION";
            sql = string.Format(sql, whId, (int)InvStoreType.物料绑定, material.ProductId);
            ds = DataAccess.SelectDataSet(sql);
            //不存在绑定物料关系
            //获取闲置的库位
            if (ds.Tables[0].Rows.Count == 0)
            {
                return GetWhLocationByFreeBindType(userNo, whId, material, qty, invIoId);
            }
            //存在关系，查询已有库存存储空间
            else
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    if (CheckStorageSpace(dr["ID"].ToString(), material, qty) &&
                        CheckLocationSpace(dr["ID"].ToString(), material, qty))
                        return dr["ID"].ToString();
                    else continue;
                }
                return GetWhLocationByFreeBindType(userNo, whId, material, qty, invIoId);
            }
        }

        //按生产订单
        private string GetWhLocationForSoStoreType(string userNo, string warehouseId, MstProductEntity material, string relatedId, string invIoId)
        {
            //根据来源单据ID、物料ID、查询类型为“按生产订单”的库位属性表
            //返回
            string sql = @"select ex.* from INV_WH_LOCATION_EX ex
inner join INV_WH_LOCATION loc on ex.ID=loc.ID
where ex.RELATED_ID='{0}' and ex.PRODUCT_ID='{1}' and ex.TYPE={2} {3}
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(warehouseId))
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "");
            }
            else
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "and loc.WH_ID='" + warehouseId + "'");
            }
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                return ds.Tables[0].Rows[0]["LOCATION_ID"].ToString();
            }
            //根据来源单据ID、查询类型为“按生产订单”的库位属性表
            //新增
            sql = @"select ex.* from INV_WH_LOCATION_EX ex
inner join INV_WH_LOCATION loc on ex.LOCATION_ID=loc.ID and loc.WH_ID='{3}'
where ex.RELATED_ID='{0}' and ex.TYPE={1}
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(warehouseId))
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "");
            }
            else
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "and loc.WH_ID='" + warehouseId + "'");
            }
            ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                InvWhLocationExEntity ex = new InvWhLocationExEntity();
                ex.Id = Guid.NewGuid().ToString();
                ex.LocationId = ds.Tables[0].Rows[0]["LOCATION_ID"].ToString();
                ex.CreatedBy = userNo;
                ex.CreatedDate = DateTime.Now;
                ex.UpdatedBy = userNo;
                ex.UpdatedDate = DateTime.Now;
                ex.IsActive = 1;
                ex.Type = (int)InvStoreType.按生产订单;
                ex.ProductId = material.ProductId;
                ex.RelatedId = relatedId;
                InvLocationExHisEntity his = new InvLocationExHisEntity();
                his.Id = Guid.NewGuid().ToString();
                his.LocationExId = ex.Id;
                his.InvIoId = invIoId;
                his.LocationId = ex.LocationId;
                his.MaterialId = material.ProductId;
                his.Type = (int)LocationExHisType.New;
                DataAccess.Insert(ex);
                DataAccess.Insert(his);
                return ex.Id;
            }
            //查询类型为“按生产订单”、来源单据ID为空 的库位属性表
            //更新
            sql = @"select ex.* from INV_WH_LOCATION_EX ex
inner join INV_WH_LOCATION loc on ex.LOCATION_ID=loc.ID
where (ex.RELATED_ID='' or ex.RELATED_ID is null) and ex.TYPE={1} and loc.WH_ID='{3}'
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(warehouseId))
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "");
            }
            else
            {
                sql = string.Format(sql, relatedId, material.ProductId, (int)InvStoreType.按生产订单, "and loc.WH_ID='" + warehouseId + "'");
            }
            ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                InvWhLocationExEntity ex = new InvWhLocationExEntity(ds.Tables[0].Rows[0]);
                ex.UpdatedBy = userNo;
                ex.UpdatedDate = DateTime.Now;
                ex.IsActive = 1;
                ex.ProductId = material.ProductId;
                ex.RelatedId = relatedId;
                InvLocationExHisEntity his = new InvLocationExHisEntity();
                his.Id = Guid.NewGuid().ToString();
                his.LocationExId = ex.Id;
                his.InvIoId = invIoId;
                his.LocationId = ex.LocationId;
                his.MaterialId = material.ProductId;
                his.HisExType = (int)InvStoreType.按生产订单;
                his.HisMaterialId = ds.Tables[0].Rows[0]["PRODUCT_ID"].ToString();
                his.HisRelatedId = null;
                his.Type = (int)LocationExHisType.Update;
                DataAccess.Update(ex);
                DataAccess.Insert(his);
                return ex.Id;
            }
            //从当前库位属性查询通用类型且物料ID空
            //更新库位属性类型为“按生产订单”
            return GetWhLocationByFreeSoType(userNo, warehouseId, material, relatedId, invIoId);
        }

        //按采购到货批次号
        /// relatedId:采购订单ID
        /// lotNo:供应商批次号
        private string GetWhLocationForPcsStoreType(string userNo, string warehouseId, MstProductEntity material, decimal qty,
            string relatedId, string lotNo, string invIoId)
        {
            //根据来源单据ID、物料ID、批次号查询类型为“按采购到货”的库位属性表
            string sql = @"select ex.* from INV_WH_LOCATION_EX ex
inner join INV_WH_LOCATION loc on ex.LOCATION_ID=loc.ID
where ex.RELATED_ID='{0}' and ex.PRODUCT_ID='{1}' and ex.LOT_NO='{2}' and ex.TYPE='{3}' {4}
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(warehouseId))
            {
                sql = string.Format(sql, relatedId, lotNo, invIoId, (int)InvStoreType.按采购到货, "");
            }
            else
            {
                sql = string.Format(sql, relatedId, lotNo, invIoId, (int)InvStoreType.按采购到货, "and loc.WH_ID='" + warehouseId + "'");
            }
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                //存在，检查库空间是否已满
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    if (CheckStorageSpace(dr["LOCATION_ID"].ToString(), material, qty))
                        return ds.Tables[0].Rows[0]["LOCATION_ID"].ToString();
                    else continue;
                }
            }
            //查询类型为“按采购到货”的库位属性表
            //更新
            sql = @"select ex.* from INV_WH_LOCATION_EX ex
inner join INV_WH_LOCATION loc on ex.LOCATION_ID=loc.ID
where ex.TYPE='{0}' {1} and (ex.RELATED_ID='' or ex.RELATED_ID is null) and (ex.PRODUCT_ID='' or ex.PRODUCT_ID is null) and (ex.LOT_NO='' or ex.LOT_NO is null) 
order by loc.STAND,loc.LOCATION";
            if (string.IsNullOrEmpty(warehouseId))
            {
                sql = string.Format(sql, (int)InvStoreType.按采购到货, "");
            }
            else
            {
                sql = string.Format(sql, (int)InvStoreType.按采购到货, "and loc.WH_ID='" + warehouseId + "'");
            }
            ds = DataAccess.SelectDataSet(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                InvWhLocationExEntity ex = new InvWhLocationExEntity(ds.Tables[0].Rows[0]);
                ex.UpdatedBy = userNo;
                ex.UpdatedDate = DateTime.Now;
                ex.IsActive = 1;
                ex.Type = (int)InvStoreType.按采购到货;
                ex.ProductId = material.ProductId;
                ex.RelatedId = relatedId;
                ex.LotNo = lotNo;
                InvLocationExHisEntity his = new InvLocationExHisEntity();
                his.Id = Guid.NewGuid().ToString();
                his.LocationExId = ex.Id;
                his.InvIoId = invIoId;
                his.LocationId = ex.LocationId;
                his.MaterialId = material.ProductId;
                his.HisExType = (int)InvStoreType.按采购到货;
                his.Type = (int)LocationExHisType.Update;
                DataAccess.Update(ex);
                DataAccess.Insert(his);
                return ex.Id;
            }
            //从当前库位属性查询通用类型且物料ID空
            //更新库位属性类型为“按生产订单”
            return GetWhLocationByFreePcsType(userNo, warehouseId, material, qty, relatedId, lotNo, invIoId);
        }

        /// <summary>
        /// 获取自动分配的库位
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public List<InvMaintainIoi> AutoAssignLocation(string userNo, List<InvMaintainIoi> items)
        {
            List<InvLocationExHisEntity> hisList = DataAccess.Select<InvLocationExHisEntity>(new InvLocationExHisEntity { InvIoId = items[0].IoId });
            List<InvWhLocationExEntity> dels = new List<InvWhLocationExEntity>();
            List<InvWhLocationExEntity> updates = new List<InvWhLocationExEntity>();
            foreach (var his in hisList)
            {
                InvWhLocationExEntity ex = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = his.LocationExId });
                if (his.Type == (int)LocationExHisType.New)
                {
                    dels.Add(ex);
                }
                if (his.Type == (int)LocationExHisType.Update)
                {
                    ex.Type = his.HisExType;
                    ex.ProductId = his.HisMaterialId;
                    ex.RelatedId = his.HisRelatedId;
                    ex.LotNo = his.HisLotNo;
                    updates.Add(ex);
                }
            }
            DataAccess.Delete(hisList);
            DataAccess.Delete(dels);
            DataAccess.Update(updates);
            foreach (var item in items)
            {
                //已存在手动分配库位，跳过
                if (!string.IsNullOrEmpty(item.LocationId) && item.Type == (int)InvStoreType.自定义)
                    continue;
                //无手动指定存储类型
                //按物料的存储类型
                //如果物料没指定存储类型，按通用类型分配
                var material = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = item.ProductId });
                if (item.Type == 0)
                {
                    if (material.StockType == null || material.StockType == 0)
                    {
                        string locationId = GetWhLocationForCommonStoreType(userNo, item.WarehouseId, material, item.Qty, item.IoId);
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                        item.LocationId = locationId;
                        item.LocationNo = loc.Location;
                        item.Stand = loc.Stand;
                        item.Type = (int)Common.InvStoreType.通用;
                        continue;
                    }
                    else
                    {
                        if (material.StockType == (int)Common.InvStoreType.通用)
                        {
                            string locationId = GetWhLocationForCommonStoreType(userNo, item.WarehouseId, material, item.Qty, item.IoId);
                            var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                            item.LocationId = locationId;
                            item.LocationNo = loc.Location;
                            item.Stand = loc.Stand;
                            item.Type = (int)Common.InvStoreType.通用;
                            continue;
                        }
                        else if (material.StockType == (int)Common.InvStoreType.物料绑定)
                        {
                            string locationId = GetWhLocationForBindStoreType(userNo, item.WarehouseId, material, item.Qty, item.IoId);
                            var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                            item.LocationId = locationId;
                            item.LocationNo = loc.Location;
                            item.Stand = loc.Stand;
                            item.Type = (int)Common.InvStoreType.物料绑定;
                            continue;
                        }
                        else if (material.StockType == (int)Common.InvStoreType.按生产订单)
                        {
                            string locationId = GetWhLocationForSoStoreType(userNo, item.WarehouseId, material, item.RelatedId, item.IoId);
                            var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                            item.LocationId = locationId;
                            item.LocationNo = loc.Location;
                            item.Stand = loc.Stand;
                            item.Type = (int)Common.InvStoreType.按生产订单;
                            continue;
                        }
                        else if (material.StockType == (int)Common.InvStoreType.按采购到货)
                        {
                            string locationId = GetWhLocationForPcsStoreType(userNo, item.WarehouseId, material, item.Qty, item.RelatedId, item.LotNo, item.IoId);
                            var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                            item.LocationId = locationId;
                            item.LocationNo = loc.Location;
                            item.Stand = loc.Stand;
                            item.Type = (int)Common.InvStoreType.按采购到货;
                            continue;
                        }
                    }
                }
                else
                {
                    if (item.Type == (int)Common.InvStoreType.通用)
                    {
                        string locationId = GetWhLocationForCommonStoreType(userNo, item.WarehouseId, material, item.Qty, item.IoId);
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                        item.LocationId = locationId;
                        item.LocationNo = loc.Location;
                        item.Stand = loc.Stand;
                        item.Type = (int)Common.InvStoreType.通用;
                        continue;
                    }
                    else if (item.Type == (int)Common.InvStoreType.物料绑定)
                    {
                        string locationId = GetWhLocationForBindStoreType(userNo, item.WarehouseId, material, item.Qty, item.IoId);
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                        item.LocationId = locationId;
                        item.LocationNo = loc.Location;
                        item.Stand = loc.Stand;
                        item.Type = (int)Common.InvStoreType.物料绑定;
                        continue;
                    }
                    else if (item.Type == (int)Common.InvStoreType.按生产订单)
                    {
                        string locationId = GetWhLocationForSoStoreType(userNo, item.WarehouseId, material, item.RelatedId, item.IoId);
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                        item.LocationId = locationId;
                        item.LocationNo = loc.Location;
                        item.Stand = loc.Stand;
                        item.Type = (int)Common.InvStoreType.按生产订单;
                        continue;
                    }
                    else if (item.Type == (int)Common.InvStoreType.按采购到货)
                    {
                        string locationId = GetWhLocationForPcsStoreType(userNo, item.WarehouseId, material, item.Qty, item.RelatedId, item.LotNo, item.IoId);
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = locationId });
                        item.LocationId = locationId;
                        item.LocationNo = loc.Location;
                        item.Stand = loc.Stand;
                        item.Type = (int)Common.InvStoreType.按采购到货;
                        continue;
                    }
                }

            }
            return items;
        }

        #endregion

        public InvWhLocationExEntity GetWhLocationExByKey(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            return DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = id });
        }

        /// <param name="userNo"></param>
        /// <param name="locId">库位ID</param>
        /// <param name="materialId">物料ID</param>
        /// <param name="invIoId"></param>
        /// <returns></returns>
        public bool UpdateWhLocationEx(InvLocationExUpdateParam param)
        {
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvWhLocationExEntity locEx = DataAccess.SelectSingle<InvWhLocationExEntity>(
                        new InvWhLocationExEntity { LocationId = param.LocId, ProductId = param.MaterialId, Type = (int)InvStoreType.自定义 });
                    if (locEx == null)
                    {
                        InvLocationExHisEntity delExHis = DataAccess.SelectSingle<InvLocationExHisEntity>(
                        new InvLocationExHisEntity
                        {
                            Type = param.SelectedExType,
                            InvIoId = param.SelectedInvIoId,
                            LocationId = param.SelectedLocId,
                            MaterialId = param.SelectedMaterialId
                        });

                        InvWhLocationExEntity updateEx = null;
                        InvWhLocationExEntity delEx = null;
                        if (delExHis != null)
                        {
                            if (delExHis.Type == (int)LocationExHisType.New)
                            {
                                delEx = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = delExHis.LocationExId });
                            }
                            if (delExHis.Type == (int)LocationExHisType.Update)
                            {
                                updateEx = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = delExHis.LocationExId });
                                updateEx.Type = delExHis.HisExType;
                                updateEx.ProductId = delExHis.HisMaterialId;
                                updateEx.RelatedId = delExHis.HisRelatedId;
                                updateEx.LotNo = delExHis.HisLotNo;
                            }
                        }

                        locEx = new InvWhLocationExEntity();
                        locEx.Id = Guid.NewGuid().ToString();
                        locEx.CreatedDate = DateTime.Now;
                        locEx.CreatedBy = param.UserNo;
                        locEx.UpdatedDate = DateTime.Now;
                        locEx.UpdatedBy = param.UserNo;
                        locEx.IsActive = 1;
                        locEx.LocationId = param.LocId;
                        locEx.Type = (int)InvStoreType.自定义;
                        locEx.ProductId = param.MaterialId;
                        InvLocationExHisEntity his = new InvLocationExHisEntity();
                        his.Id = Guid.NewGuid().ToString();
                        his.InvIoId = param.InvIoId;
                        his.LocationId = locEx.LocationId;
                        his.Type = (int)LocationExHisType.New;

                        broker.BeginTransaction();
                        if(delExHis!=null)
                            DataAccess.Delete(delExHis, broker);
                        if (delEx != null)
                            DataAccess.Delete(delEx, broker);
                        if (updateEx != null)
                            DataAccess.Update(updateEx, broker);
                        DataAccess.Insert(locEx, broker);
                        DataAccess.Insert(his, broker);
                        broker.Commit();
                        return true;
                    }
                    else
                    {
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return false;
                }
            }
        }

        public bool DelWhLocationEx(InvLocationExDelParam param)
        {
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvLocationExHisEntity delExHis = DataAccess.SelectSingle<InvLocationExHisEntity>(
                        new InvLocationExHisEntity
                        {
                            Type = param.SelectedExType,
                            InvIoId = param.SelectedInvIoId,
                            LocationId = param.SelectedLocId,
                            MaterialId = param.SelectedMaterialId
                        });
                    InvWhLocationExEntity updateEx = null;
                    InvWhLocationExEntity delEx = null;
                    if (delExHis != null)
                    {
                        if (delExHis.Type == (int)LocationExHisType.New)
                        {
                            delEx = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = delExHis.LocationExId });
                        }
                        if (delExHis.Type == (int)LocationExHisType.Update)
                        {
                            updateEx = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = delExHis.LocationExId });
                            updateEx.Type = delExHis.HisExType;
                            updateEx.ProductId = delExHis.HisMaterialId;
                            updateEx.RelatedId = delExHis.HisRelatedId;
                            updateEx.LotNo = delExHis.HisLotNo;
                        }
                    }

                    broker.BeginTransaction();
                    DataAccess.Delete(delExHis, broker);
                    if (delEx != null)
                        DataAccess.Delete(delEx, broker);
                    if (updateEx != null)
                        DataAccess.Update(updateEx, broker);
                    broker.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return false;
                }
            }
        }


        /// <summary>
        /// 入库
        /// 更新库存表
        /// 按库存类型，更新库位关系表
        /// 更新库存历史明细表
        /// </summary>
        /// <param name="userNo"></param>
        /// <param name="ds"></param>
        /// <returns></returns>
        public InvStockInResultMessage StockIn(string userNo, List<InvMaintainIoi> items)
        {
            if (string.IsNullOrEmpty(userNo))
                return new InvStockInResultMessage { Result = false, Message = "userNo为空" };
            if (items == null || items.Count == 0)
                return new InvStockInResultMessage { Result = false, Message = "items为空" };
            var io = InvIoBs.GetInvIo(new InvIoEntity { Id = items[0].IoId });
            if (io == null)
                return new InvStockInResultMessage { Result = false, Message = "入库单错误不存在" };

            List<InvWhLocationExEntity> addLocEx = new List<InvWhLocationExEntity>();
            List<InvWhLocationExEntity> updateLocEx = new List<InvWhLocationExEntity>();
            List<InvStgEntity> addStg = new List<InvStgEntity>();
            List<InvStgEntity> updateStg = new List<InvStgEntity>();
            List<InvStgHisEntity> addStgHis = new List<InvStgHisEntity>();
            List<ProdWipMtrlCurEntity> updateWipMtrl = new List<ProdWipMtrlCurEntity>();
            List<ProdWipMtrlCurEntity> deleteWipMtrl = new List<ProdWipMtrlCurEntity>();
            InvMtrlTransEntity mtrlTrans = null;//工单退料交易索引 
            InvProdInventoryEntity prodInventory = null; //工单入库交易索引
            InvIappEntity iapp = null;
            ProdWoEntity wo = null;
            List<ProdWipCurEntity> deleteWip = new List<ProdWipCurEntity>();
            List<ProdWipCurEntity> updateWip = new List<ProdWipCurEntity>();
            List<ProdWipCurEntity> insWip = new List<ProdWipCurEntity>();
            List<ProdWipHisEntity> insertWipInventoryHis = new List<ProdWipHisEntity>();
            List<PurArvItemEntity> updateArvItems = new List<PurArvItemEntity>();
            List<PurPoItemEntity> updatePoItems = new List<PurPoItemEntity>();

            if (io.Type == (int)Common.InvInType.工单退料)
            {
                mtrlTrans = InvMtrlTransBs.GetInvMtrlTrans(new InvMtrlTransEntity { TransNo = io.RelatedId });
            }
            else if (io.Type == (int)Common.InvInType.工单入库)
                prodInventory = InvProdInventoryBs.GetInvProdInventory(new InvProdInventoryEntity { InvNo = io.RelatedId });

            //累计交易数
            decimal totalQty = 0;
            foreach (var item in items)
            {
                totalQty += item.Qty;
                //如果是工单退料，更改工单在线物料量
                if (io.Type == (int)Common.InvInType.工单退料)
                {
                    #region 工单退料
                    ProdWipMtrlCurEntity wipMtrl = ProdWipMtrlCurBs.GetProdWipMtrlCur(new ProdWipMtrlCurEntity { WoNo = mtrlTrans.WoNo, MtrlCode = item.ProductCode });
                    if (wipMtrl.MtrlQty > item.Qty)
                    {
                        wipMtrl.MtrlQty = wipMtrl.MtrlQty - item.Qty;
                        updateWipMtrl.Add(wipMtrl);
                    }
                    else if (wipMtrl.MtrlQty == item.Qty)
                    {
                        deleteWipMtrl.Add(wipMtrl);
                    }
                    else
                    {

                        string msg = string.Format(@"物料'{0}'无法入库，工单可退料量不足：{1}", item.ProductName, wipMtrl.MtrlQty.ToString());
                        return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };
                    }
                    #endregion
                }

                var rel = InvWhLocationExBs.GetInvWhLocationEx(new InvWhLocationExEntity { Id = item.LocationId });
                if (rel != null)
                {
                    if (rel.Type == item.Type)
                    {
                        #region 存储类型
                        if (item.Type == 10)//通用
                        {
                            if (string.IsNullOrEmpty(rel.ProductId))
                            {
                                rel.ProductId = item.ProductId;
                                rel.UpdatedBy = userNo;
                                rel.UpdatedDate = DateTime.Now;
                                updateLocEx.Add(rel);
                            }
                            else if (!rel.ProductId.Equals(item.ProductId))
                            {
                                //报错，记录日志
                                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = rel.ProductId });
                                string msg = string.Format(@"物料'{0}'无法入库，库位'{1}'已存在物料'{2}'", item.ProductName, item.LocationNo, product.ProductName);
                                return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };
                            }
                        }
                        else if (item.Type == 20)//物料绑定
                        {
                            if (string.IsNullOrEmpty(rel.ProductId))
                            {
                                rel.ProductId = item.ProductId;
                                rel.UpdatedBy = userNo;
                                rel.UpdatedDate = DateTime.Now;
                                updateLocEx.Add(rel);
                            }
                            else if (!rel.ProductId.Equals(item.ProductId))
                            {
                                //报错，记录日志
                                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = rel.ProductId });
                                string msg = string.Format(@"物料'{0}'无法入库，库位'{1}'已存在物料'{2}'", item.ProductName, item.LocationNo, product.ProductName);
                                return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };
                            }
                        }
                        else if (item.Type == 30)//按生产订单
                        {
                            if (string.IsNullOrEmpty(rel.ProductId))
                            {
                                rel.RelatedId = item.RelatedId;
                                rel.UpdatedBy = userNo;
                                rel.UpdatedDate = DateTime.Now;
                                updateLocEx.Add(rel);
                            }
                            else if (!rel.RelatedId.Equals(item.RelatedId))
                            {
                                //报错，记录日志
                                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = rel.ProductId });
                                string msg = string.Format(@"库位'{0}'对应生产订单错误", item.LocationNo);
                                return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };

                            }
                        }
                        else if (item.Type == 40)//按工单任务
                        {
                            if (string.IsNullOrEmpty(rel.ProductId) && string.IsNullOrEmpty(rel.RelatedId))
                            {
                                rel.ProductId = item.ProductId;
                                rel.RelatedId = item.RelatedId;
                                rel.UpdatedBy = userNo;
                                rel.UpdatedDate = DateTime.Now;
                                updateLocEx.Add(rel);
                            }
                            else if (!rel.ProductId.Equals(item.ProductId) || !rel.RelatedId.Equals(item.RelatedId))
                            {
                                //报错，记录日志
                                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = rel.ProductId });
                                string msg = string.Format(@"物料'{0}'无法入库，库位'{1}'对应工单任务错误", item.ProductName, item.LocationNo);
                                return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };

                            }
                        }
                        else if (item.Type == 50)//按采购到货批号
                        {
                        }
                        else return new InvStockInResultMessage { Result = false, Id = item.Id, Message = "库存类型错误" };
                        #endregion
                    }
                    else if (rel.Type == 10)
                    {
                        if (string.IsNullOrEmpty(rel.ProductId))
                        {
                            rel.ProductId = item.ProductId;
                            rel.RelatedId = item.RelatedId;
                            rel.UpdatedBy = userNo;
                            rel.UpdatedDate = DateTime.Now;
                            updateLocEx.Add(rel);
                        }
                        else
                        {
                            var t = InvStgBs.GetInvStg(new InvStgEntity { LocationId = rel.Id, ProductId = rel.ProductId });
                            if (t == null || t.CurrentQty == 0)
                            {
                                rel.ProductId = item.ProductId;
                                rel.RelatedId = item.RelatedId;
                                rel.UpdatedBy = userNo;
                                rel.UpdatedDate = DateTime.Now;
                                updateLocEx.Add(rel);
                            }
                            else
                            {
                                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = rel.ProductId });
                                string msg = string.Format(@"物料'{0}'无法入库，库位'{1}'已存在物料'{2}'", item.ProductName, item.LocationNo, product.ProductName);
                                return new InvStockInResultMessage { Result = false, Id = item.Id, Message = msg };
                            }
                        }

                    }
                }
                //更新库存表及历史明细
                var stg = InvStgBs.GetInvStg(new InvStgEntity { LocationId = item.LocationId, ProductId = item.ProductId });
                if (stg != null)
                {
                    stg.CurrentQty += item.Qty;
                    updateStg.Add(stg);
                }
                else
                {
                    stg = new InvStgEntity();
                    stg.Id = Guid.NewGuid().ToString();
                    stg.LocationId = item.LocationId;
                    stg.ProductId = item.ProductId;
                    stg.CurrentQty = item.Qty;
                    stg.FixedQty = 0;
                    stg.UpdatedDate = DateTime.Now;
                    addStg.Add(stg);
                }

                var stgHis = new InvStgHisEntity();
                stgHis.Id = Guid.NewGuid().ToString();
                stgHis.ProductId = item.ProductId;
                stgHis.Type = io.Type;
                if (!string.IsNullOrEmpty(item.RelatedId))
                    stgHis.RelatedId = item.RelatedId;
                stgHis.LocationId = item.LocationId;
                stgHis.QtyIn = item.Qty;
                stgHis.CreatedBy = userNo;
                stgHis.CreatedDate = DateTime.Now;
                addStgHis.Add(stgHis);

                if (io.Type == (int)InvInType.采购入库)
                {
                    PurPoItemEntity poItem = PurPoItemBs.GetPoItemByInvIo(item.RelatedId, item.ProductId);
                    if (poItem != null)
                    {
                        poItem.AcpQty = item.Qty;
                        updatePoItems.Add(poItem);
                    }
                }
                if (io.Type == (int)InvInType.采购到货入库)
                {
                    PurArvItemEntity arvItem = PurArvItemBs.GetArvItemForInvIoi(item.RelatedId, item.ProductId);
                    if (arvItem != null)
                    {
                        arvItem.StockInQty += item.Qty;
                        arvItem.LocationId = item.LocationId;
                        arvItem.LocationNo = item.LocationNo;
                        updateArvItems.Add(arvItem);

                        PurPoItemEntity poItem = DataAccess.SelectSingle<PurPoItemEntity>(new PurPoItemEntity { Id = arvItem.PoItemId });
                        if (poItem != null)
                        {
                            poItem.AcpQty += item.Qty;
                            updatePoItems.Add(poItem);
                        }
                    }
                }
                if (io.Type == (int)InvInType.采购质检入库)
                {
                    QcIqcEntity iqc = DataAccess.SelectSingle<QcIqcEntity>(new QcIqcEntity { Id = item.RelatedId });
                    PurArvItemEntity arvItem = ESOL.Business.Qc.QcIqcBs.GetArvItemForQcIqc(item.RelatedId);
                    if (arvItem != null && iqc != null)
                    {
                        arvItem.StockInQty += item.Qty;
                        arvItem.AcpQty += iqc.AcptQty;
                        arvItem.RejQty += iqc.RejQty;
                        arvItem.LocationId = item.LocationId;
                        arvItem.LocationNo = item.LocationNo;
                        updateArvItems.Add(arvItem);
                        PurPoItemEntity poItem = DataAccess.SelectSingle<PurPoItemEntity>(new PurPoItemEntity { Id = arvItem.PoItemId });
                        if (poItem != null)
                        {
                            poItem.AcpQty += item.Qty;
                            updatePoItems.Add(poItem);
                        }
                    }
                }

            }

            #region 工单入库
            if (io.Type == (int)Common.InvInType.工单入库)
            {
                List<InvProdInventoryItemEntity> invItems = InvProdInventoryBs.GetProdInventoryItems(new InvProdInventoryEntity { InvNo = io.RelatedId });
                if (invItems == null) throw (new Exception("没有找到入库单:" + io.RelatedId));
                decimal reqInventoryQty = 0;
                #region 更新在制品状态finished-->Inv
                foreach (InvProdInventoryItemEntity item in invItems)
                {
                    reqInventoryQty += item.ProdQty;
                    var wip = ProdWipCurBs.GetProdWipCur(new ProdWipCurEntity { WoNo = prodInventory.WoNo, TechnicItemId = item.TechnicItemId, CurWorkgroupNo = item.CurWorkgroupNo, Status = Common.ProdStatus.PS_FINISH.ToString() });
                    if (wip == null)
                        throw (new Exception("没有找到可以入库的在制品。 wo:" + prodInventory.WoNo + ",technic:" + item.TechnicItemId + " ,WorkgroupNo:" + item.CurWorkgroupNo));


                    //修改完工状态的在制品记录
                    if (wip.Qty > item.ProdQty)
                    {
                        wip.Qty = wip.Qty - item.ProdQty;
                        updateWip.Add(wip);
                    }
                    else if (wip.Qty == item.ProdQty)
                    {
                        deleteWip.Add(wip);
                    }
                    else
                        throw (new Exception("没有足够的可入库在制品！ wo:" + prodInventory.WoNo + ",technic:" + item.TechnicItemId + " ,WorkgroupNo:" + item.CurWorkgroupNo));


                    var invWip = ProdWipCurBs.GetProdWipCur(new ProdWipCurEntity { WoNo = prodInventory.WoNo, TechnicItemId = item.TechnicItemId, CurWorkgroupNo = item.CurWorkgroupNo, Status = "INV" });
                    ////修改入库状态的在制品记录
                    if (invWip != null)
                    {//已存在入库状态的记录
                        invWip.Qty = invWip.Qty + item.ProdQty;
                        updateWip.Add(invWip);
                    }
                    else
                    {
                        invWip = wip;
                        invWip.Id = Guid.NewGuid().ToString();
                        invWip.Qty = item.ProdQty;
                        invWip.Status = "INV";
                        insWip.Add(invWip);
                    }
                    ProdWipHisEntity wiphis = InvProdInventoryBs.GetWipInventoryHis(wip, prodInventory.InvNo, "INV");
                    insertWipInventoryHis.Add(wiphis);
                }
                #endregion

                #region 改变工单入库数
                wo = ProdWoBs.GetProdWo(new ProdWoEntity { WoNo = prodInventory.WoNo });
                if (wo == null) throw (new Exception("工单:" + prodInventory.WoNo + "不存在！"));
                wo.StorageQty += totalQty;
                if (wo.StorageQty >= wo.Qty)
                    wo.Status = Common.WoStatus.WOS_Finish.ToString();
                #endregion

                #region 改变入库单状态


                if (totalQty == reqInventoryQty)
                {
                    iapp = InvIappBs.GetInvIapp(new InvIappEntity { RelatedId = io.RelatedId });
                    iapp.Status = Common.WfStatus.WFS30.ToString();
                    prodInventory.Status = Common.WoTransStatus.Finished.ToString();

                }
                else
                    prodInventory = null;


                #endregion
            }
            #endregion

            if (io.Type == (int)Common.InvInType.工单退料)
            {
                if (InvStgBs.StockIn(addLocEx, addStg, updateStg, addStgHis, updateWipMtrl, deleteWipMtrl))
                    return new InvStockInResultMessage { Result = true };
                else
                    return new InvStockInResultMessage { Result = false, Message = "保存失败" };
            }
            else if (io.Type == (int)Common.InvInType.工单入库)
            {

                if (InvStgBs.StockIn(addLocEx, addStg, updateStg, addStgHis, deleteWip, updateWip, insWip, insertWipInventoryHis
                                     , wo, prodInventory, iapp))
                    return new InvStockInResultMessage { Result = true };
                else
                    return new InvStockInResultMessage { Result = false, Message = "保存失败" };
            }
            else
            {
                using (DataAccessBroker broker = DataAccessFactory.Instance())
                {
                    try
                    {
                        io.Status = WfStatus.WFS30.ToString();
                        List<InvLocationExHisEntity> delExHis = DataAccess.Select<InvLocationExHisEntity>(new InvLocationExHisEntity { InvIoId = items[0].IoId });

                        broker.BeginTransaction();
                        DataAccess.Insert(addStg, broker);
                        DataAccess.Update(updateStg, broker);
                        DataAccess.Insert(addStgHis, broker);
                        DataAccess.Delete(delExHis, broker);
                        DataAccess.Update(io, broker);
                        DataAccess.Update(updateArvItems, broker);
                        DataAccess.Update(updatePoItems, broker);
                        broker.Commit();
                        return new InvStockInResultMessage { Result = true };
                    }
                    catch (Exception ex)
                    {
                        broker.RollBack();
                        MyDebug.write(ex.Message);
                        return new InvStockInResultMessage { Result = false, Message = "保存失败" };
                    }
                }

            }

        }

        /// <summary>
        /// 查询库存
        /// </summary>
        /// <param name="con"></param>
        /// <returns></returns>
        public DataSet GetStgAllDsByCondition(InvStgQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and loc.WH_ID='" + con.WhId + "'";
            }
            if (!string.IsNullOrEmpty(con.ParentType))
            {
                condition += " and t.PARENT_TYPE_ID='" + con.WhId + "'";
            }
            if (!string.IsNullOrEmpty(con.ChildType))
            {
                condition += " and p.PRODUCT_TYPE_ID='" + con.ChildType + "'";
            }
            if (!string.IsNullOrEmpty(con.ProductName))
            {
                condition += " and p.PRODUCT_NAME like '%" + con.ProductName + "%'";
            }
            if (!string.IsNullOrEmpty(con.ProductCode))
            {
                condition += " and p.PRODUCT_CODE='" + con.ProductCode + "'";
            }
            condition += " and wh.IS_LOCK=" + con.IsLock + "";
            condition += " and loc.IS_ACTIVE=" + con.IsActive + "";

            return InvStgBs.GetAllDsByCondition(pageIndex, pageSize, condition);
        }

        #region 盘点

        public InvMaintainCApp AddInvCApp(InvMaintainCApp capp)
        {
            if (capp == null)
                return null;
            capp.CreatedDate = DateTime.Now;
            capp.UpdatedDate = DateTime.Now;
            capp.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvCApp");
            capp.Status = Common.WfStatus.WFS10.ToString();

            InvCappEntity app = new InvCappEntity();
            app.Id = capp.Id;
            app.CreatedBy = capp.CreatedBy;
            app.CreatedDate = capp.CreatedDate;
            app.UpdatedBy = capp.UpdatedBy;
            app.UpdatedDate = capp.UpdatedDate;
            app.IsActive = capp.IsActive;
            app.AppNo = capp.AppNo;
            app.BeginDate = capp.BeginDate;
            app.EndDate = capp.EndDate;
            app.Remark = capp.Remark;
            app.Status = capp.Status;
            if (InvCappBs.InsertInvCapp(app))
                return capp;
            else return null;

        }

        public InvMaintainCApp UpdateInvCApp(InvMaintainCApp capp)
        {
            if (capp == null)
                return null;
            capp.UpdatedDate = DateTime.Now;

            InvCappEntity app = InvCappBs.GetInvCapp(new InvCappEntity { Id = capp.Id });
            if (app == null)
                return null;
            app.UpdatedBy = capp.UpdatedBy;
            app.UpdatedDate = capp.UpdatedDate;
            app.IsActive = capp.IsActive;
            app.AppNo = capp.AppNo;
            app.BeginDate = capp.BeginDate;
            app.EndDate = capp.EndDate;
            app.Remark = capp.Remark;
            app.Status = capp.Status;
            if (InvCappBs.UpdateInvCapp(app))
                return capp;
            else return null;
        }

        public int? DelInvCApp(InvMaintainCApp capp)
        {
            if (capp == null)
                return 1;
            InvCappEntity app = InvCappBs.GetInvCapp(new InvCappEntity { Id = capp.Id });
            if (app == null)
                return 2;
            if (InvCappBs.DeleteInvCapp(app))
                return null;
            else return -1;

        }

        public int? DelInvCAppEntity(InvCappEntity capp)
        {
            if (capp == null)
                return 1;
            if (InvCappBs.DeleteInvCapp(capp))
                return null;
            else return -1;
        }

        public InvMaintainCApp GetMaintainCAppByKey(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            var capp = InvCappBs.GetInvCapp(new InvCappEntity { Id = id });
            if (capp == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            InvMaintainCApp result = new InvMaintainCApp();
            result.Id = capp.Id;
            result.CreatedBy = capp.CreatedBy;
            if (!string.IsNullOrEmpty(capp.CreatedBy))
            {
                var createdUser = ps.getUser(null, capp.CreatedBy);
                result.CreatedUser = createdUser.firstName;
            }
            result.CreatedDate = capp.CreatedDate;
            result.UpdatedBy = capp.UpdatedBy;
            if (!string.IsNullOrEmpty(capp.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, capp.UpdatedBy);
                result.UpdatedUser = updatedUser.firstName;
            }
            result.UpdatedDate = capp.UpdatedDate;

            result.IsActive = capp.IsActive;
            result.AppNo = capp.AppNo;
            result.WhId = capp.WhId;
            result.BeginDate = capp.BeginDate;
            result.EndDate = capp.EndDate;
            result.Remark = capp.Remark;
            result.Status = capp.Status;
            return result;

        }

        public DataSet GetCAppAllDsByCondition(InvCAppQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and app.WH_ID='" + con.WhId + "'";
            }
            if (con.CreatedDateFrom != null && con.CreatedDateFrom != new DateTime(1, 1, 1))
            {
                condition += " and app.CREATED_DATE>=" + con.CreatedDateFrom.ToString("yyyy-MM-dd HH:mm:ss") + "'";
            }
            if (con.CreatedDateTo != null && con.CreatedDateTo != new DateTime(1, 1, 1))
            {
                condition += " and app.CREATED_DATE<=" + con.CreatedDateTo.ToString("yyyy-MM-dd HH:mm:ss") + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and app.STATUS='" + con.Status + "'";
            }
            return InvCappBs.GetAllDsByCondition(pageIndex, pageSize, condition);

        }

        public InvCoEntity CAppToCo(string userNo, InvMaintainCApp capp)
        {
            if (capp == null)
                return null;
            InvCoEntity co = new InvCoEntity();
            co.Id = Guid.NewGuid().ToString();
            co.CreatedBy = userNo;
            co.CreatedDate = DateTime.Now;
            co.UpdatedBy = userNo;
            co.UpdatedDate = DateTime.Now;
            co.IsActive = 1;
            co.CappId = capp.Id;
            co.WhId = capp.WhId;
            co.CoNo = MstCodeRuleBs.GetCurrentOrderCode("InvCo");
            co.BeginDate = capp.BeginDate;
            co.FinishDate = capp.EndDate;
            co.Remark = capp.Remark;
            co.Status = Common.WfStatus.WFS10.ToString();

            var coi = new List<InvCoiEntity>();
            string sql = @"select loc.*,stg.CURRENT_QTY,stg.PRODUCT_ID,ex.ID as LOCATION_ID,ex.TYPE 
from INV_WH_LOCATION loc
inner join INV_WH_LOCATION_EX ex on loc.ID=ex.LOCATION_ID
left join INV_STG stg on loc.ID=stg.LOCATION_ID
where loc.WH_ID='{0}'";
            sql = string.Format(sql, capp.WhId);
            DataSet ds = InvWhLocationBs.GetWhLocsBySql(sql);
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                var c = new InvCoiEntity();
                c.Id = Guid.NewGuid().ToString();
                c.CoId = co.Id;
                c.ProductId = dr["PRODUCT_ID"].ToString();
                if (dr["CURRENT_QTY"] != DBNull.Value)
                    c.CurQty = Convert.ToDecimal(dr["CURRENT_QTY"]);
                if (dr["ID"] != DBNull.Value)
                    c.LocationId = dr["ID"].ToString();
                if (dr["LOCATION_ID"] != DBNull.Value)
                    c.LocationExId = dr["LOCATION_ID"].ToString();
                if (dr["TYPE"] != DBNull.Value)
                    c.Type = (int)dr["TYPE"];
                coi.Add(c);
            }

            //更新盘库申请表状态
            var app = DataAccess.SelectSingle<InvCappEntity>(new InvCappEntity { Id = capp.Id });
            if (app != null)
            {
                app.Status = WfStatus.WFS20.ToString();
            }

            //锁库，更新仓库表
            var wh = DataAccess.SelectSingle<InvWhEntity>(new InvWhEntity { Id = capp.WhId });
            if (wh != null)
            {
                wh.IsLock = 1;
            }

            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Update(wh, broker);
                    DataAccess.Update(app, broker);
                    DataAccess.Insert(co, broker);
                    DataAccess.Insert(coi, broker);
                    broker.Commit();
                    return co;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return null;
                }
            }

        }


        public InvMaintainCo AddInvCo(InvMaintainCo co)
        {
            if (co == null)
                return null;
            co.CreatedDate = DateTime.Now;
            co.UpdatedDate = DateTime.Now;
            co.CoNo = MstCodeRuleBs.GetCurrentOrderCode("InvCo");
            co.Status = Common.WfStatus.WFS10.ToString();

            InvCoEntity c = new InvCoEntity();
            c.Id = co.Id;
            c.CreatedBy = co.CreatedBy;
            c.CreatedDate = co.CreatedDate;
            c.UpdatedBy = co.UpdatedBy;
            c.UpdatedDate = co.UpdatedDate;
            c.IsActive = co.IsActive;
            c.CoNo = co.CoNo;
            c.BeginDate = co.BeginDate;
            c.FinishDate = co.EndDate;
            c.Remark = co.Remark;
            c.Status = co.Status;
            if (InvCoBs.InsertInvCo(c))
                return co;
            else return null;

        }

        public InvMaintainCo UpdateInvCo(InvMaintainCo co)
        {
            if (co == null)
                return null;
            co.UpdatedDate = DateTime.Now;

            var c = InvCoBs.GetInvCo(new InvCoEntity { Id = co.Id });
            if (c == null)
                return null;
            c.UpdatedBy = co.UpdatedBy;
            c.UpdatedDate = co.UpdatedDate;
            c.IsActive = co.IsActive;
            c.CoNo = co.CoNo;
            c.BeginDate = co.BeginDate;
            c.FinishDate = co.EndDate;
            c.Remark = co.Remark;
            c.Status = co.Status;
            if (InvCoBs.UpdateInvCo(c))
                return co;
            else return null;
        }

        public int? DelInvCo(InvMaintainCo co)
        {
            if (co == null)
                return 1;
            var c = InvCoBs.GetInvCo(new InvCoEntity { Id = co.Id });
            if (c == null)
                return 2;
            if (InvCoBs.DeleteInvCo(c))
                return null;
            else return -1;

        }

        public int? DelInvCoi(InvMaintainCoi coi)
        {
            if (coi == null)
                return 1;
            var c = InvCoiBs.GetInvCoi(new InvCoiEntity { Id = coi.Id });
            if (c == null)
                return 2;
            if (InvCoiBs.DeleteInvCoi(c))
                return null;
            else return -1;

        }

        public int? SaveInvCoiList(List<InvMaintainCoi> coi)
        {
            if (coi == null)
                return 1;
            if (coi.Count == 0)
                return 2;
            List<InvCoiEntity> adds = new List<InvCoiEntity>();
            List<InvCoiEntity> updates = new List<InvCoiEntity>();
            foreach (var c in coi)
            {
                var r = InvCoiBs.GetInvCoi(new InvCoiEntity { Id = c.Id });
                if (r == null)
                {
                    InvCoiEntity add = new InvCoiEntity();
                    add.Id = c.Id;
                    add.CoId = c.CoId;
                    add.ProductId = c.ProductId;
                    add.CurQty = c.CurQty;
                    add.ChkQty = c.ChkQty;
                    add.LocationId = c.LocationId;
                    add.Remark = c.Remark;
                    adds.Add(add);
                }
                else
                {
                    r.CoId = c.CoId;
                    r.ProductId = c.ProductId;
                    r.CurQty = c.CurQty;
                    r.ChkQty = c.ChkQty;
                    r.LocationId = c.LocationId;
                    r.Remark = c.Remark;
                    updates.Add(r);
                }
            }
            if (InvCoiBs.Save(adds, updates))
                return null;
            else return -1;
        }

        public InvMaintainCo GetMaintainCoByKey(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            var co = InvCoBs.GetInvCo(new InvCoEntity { Id = id });
            if (co == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            InvMaintainCo result = new InvMaintainCo();
            result.Id = co.Id;
            result.CreatedBy = co.CreatedBy;
            if (!string.IsNullOrEmpty(co.CreatedBy))
            {
                var createdUser = ps.getUser(null, co.CreatedBy);
                result.CreatedUser = createdUser.firstName;
            }
            result.CreatedDate = co.CreatedDate;
            result.UpdatedBy = co.UpdatedBy;
            if (!string.IsNullOrEmpty(co.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, co.UpdatedBy);
                result.UpdatedUser = updatedUser.firstName;
            }
            result.UpdatedDate = co.UpdatedDate;

            result.IsActive = co.IsActive;
            result.CoNo = co.CoNo;
            result.WhId = co.WhId;
            result.BeginDate = co.BeginDate;
            result.EndDate = co.FinishDate;
            result.Remark = co.Remark;
            result.Status = co.Status;
            return result;

        }


        public System.Data.DataSet GetCoAllDsByCondition(InvCoQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and co.WH_ID='" + con.WhId + "'";
            }
            if (!string.IsNullOrEmpty(con.CoNo))
            {
                condition += " and co.CO_NO='" + con.CoNo + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and co.STATUS='" + con.Status + "'";
            }
            return InvCoBs.GetAllDsByCondition(pageIndex, pageSize, condition);
        }

        public List<InvMaintainCoi> GetCoiAllListByCoId(string coId)
        {
            if (string.IsNullOrEmpty(coId))
                return null;
            string sql = @"select coi.*,loc.STAND,loc.LOCATION,loc.VOLUME,loc.AREA,p.PRODUCT_NAME,p.PRODUCT_CODE 
from INV_COI coi
left join INV_WH_LOCATION loc on coi.LOCATION_ID=loc.ID
left join MST_PRODUCT p on coi.PRODUCT_ID=p.PRODUCT_ID
where coi.CO_ID='{0}'";
            DataSet ds = InvCoiBs.GetAllDsBySql(sql);
            List<InvMaintainCoi> result = new List<InvMaintainCoi>();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                InvMaintainCoi coi = new InvMaintainCoi();
                coi.Id = dr["ID"].ToString();
                coi.CoId = dr["CO_ID"].ToString();
                coi.LocationId = dr["LOCATION_ID"].ToString();
                coi.Stand = dr["STAND"].ToString();
                coi.LocationNo = dr["LOCATION"].ToString();
                coi.Volume = (decimal)dr["VOLUME"];
                coi.Area = (decimal)dr["AREA"];
                coi.ProductId = dr["PRODUCT_ID"].ToString();
                coi.ProductName = dr["PRODUCT_NAME"].ToString();
                coi.ProductCode = dr["PRODUCT_CODE"].ToString();
                coi.CurQty = (decimal)dr["CUR_QTY"];
                if (dr["CHK_QTY"] != null)
                {
                    coi.ChkQty = (decimal)dr["CHK_QTY"];
                    coi.DiffQty = coi.ChkQty - coi.CurQty;
                }
                coi.Remark = dr["REMARK"].ToString();
                result.Add(coi);
            }
            return result;

        }

        /// <summary>
        /// 检查盘库时库位仓储类型
        /// 暂时不检查库位空间是否足够
        /// </summary>
        /// <param name="userNo"></param>
        /// <param name="locId"></param>
        /// <param name="productId"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        public string CheckLocation(string userNo, string locId, string productId, decimal qty)
        {
            if (string.IsNullOrEmpty(locId) || string.IsNullOrEmpty(productId))
                return "库位或产品不能为空！";
            var ex = InvWhLocationExBs.GetInvWhLocationEx(new InvWhLocationExEntity { Id = locId });
            if (ex == null)
            {
                ex.Id = locId;
                ex.CreatedBy = userNo;
                ex.CreatedDate = DateTime.Now;
                ex.UpdatedBy = userNo;
                ex.UpdatedDate = DateTime.Now;
                ex.IsActive = 1;
                ex.Type = 10;
                ex.ProductId = productId;
                if (InvWhLocationExBs.InsertInvWhLocationEx(ex))
                    return null;
                else return "维护库位仓储类型信息失败！";
            }
            if (ex.Type == 30 || ex.Type == 40 || ex.Type == 50)
            {
                string result = "库位仓储类型为:\"{0}\"，不允许盘点！";
                result = string.Format(result, InvStoreType.按生产订单.ToString());
                return result;
            }
            else if (ex.Type == 40)
            {
                string result = "库位仓储类型为:\"{0}\"，不允许盘点！";
                result = string.Format(result, InvStoreType.按工单任务.ToString());
                return result;
            }
            else if (ex.Type == 50)
            {
                string result = "库位仓储类型为:\"{0}\"，不允许盘点！";
                result = string.Format(result, InvStoreType.按采购到货.ToString());
                return result;
            }
            else if (ex.Type == 10)
            {
                ex.ProductId = productId;
                ex.UpdatedDate = DateTime.Now;
                ex.UpdatedBy = userNo;
                if (InvWhLocationExBs.UpdateInvWhLocationEx(ex))
                    return null;
                else return "维护库位仓储类型信息失败！";
            }
            else if (ex.Type == 20 && !ex.ProductId.Equals(productId))
            {
                var product = MstProductBs.GetMstProduct(new MstProductEntity { ProductId = ex.ProductId });
                string result = "库位仓储类型为:\"{0}\"，已绑定产品:\"{1}({2})\"";
                result = string.Format(result, InvStoreType.物料绑定.ToString(), product.ProductName, product.ProductCode);
                return result;
            }
            return null;

        }

        /// <summary>
        /// 盘库
        /// 更新库存表、历史
        /// </summary>
        /// <param name="coi"></param>
        /// <returns></returns>
        public int? MakeInv(string userNo, List<InvMaintainCoi> coi)
        {
            if (coi == null)
                return 1;
            if (coi.Count == 0)
                return 2;
            var co = DataAccess.SelectSingle<InvCoEntity>(new InvCoEntity { Id = coi[0].CoId });
            if (co == null)
                return 3;
            var capp = DataAccess.SelectSingle<InvCappEntity>(new InvCappEntity { Id = co.CappId });
            if (capp == null)
                return 4;
            var wh = DataAccess.SelectSingle<InvWhEntity>(new InvWhEntity { Id = co.WhId });
            if (wh == null)
                return 5;
            var addsEx = new List<InvWhLocationExEntity>();
            var updatedsEx = new List<InvWhLocationExEntity>();
            var delsEx = new List<InvWhLocationExEntity>();

            var addsStg = new List<InvStgEntity>();
            var updatesStg = new List<InvStgEntity>();
            var delsStg = new List<InvStgEntity>();

            var addsStgHis = new List<InvStgHisEntity>();

            foreach (var item in coi)
            {
                var stg = InvStgBs.GetInvStg(new InvStgEntity { LocationId = item.LocationId, ProductId = item.ProductId });
                InvWhLocationExEntity locationEx = null;
                if (!string.IsNullOrEmpty(item.LocationExId))
                {
                    locationEx = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity { Id = item.LocationExId });
                }
                #region 通用
                if (item.Type == (int)InvStoreType.通用)
                {
                    if (item.CurQty == 0 && item.ChkQty == 0)
                    {
                    }
                    if (item.CurQty != 0 && item.ChkQty != 0 && item.CurQty != item.ChkQty)
                    {
                        stg.CurrentQty = item.ChkQty;
                        updatesStg.Add(stg);
                    }
                    if (item.CurQty != 0 && item.ChkQty == 0)
                    {
                        delsStg.Add(stg);
                        locationEx.ProductId = null;
                        updatedsEx.Add(locationEx);
                    }
                    if (item.CurQty == 0 && item.ChkQty != 0)
                    {
                        stg = new InvStgEntity();
                        stg.Id = Guid.NewGuid().ToString();
                        stg.LocationId = item.LocationId;
                        stg.ProductId = item.ProductId;
                        stg.CurrentQty = item.CurQty;
                        stg.UpdatedDate = DateTime.Now;
                        addsStg.Add(stg);
                        locationEx.UpdatedDate = DateTime.Now;
                        locationEx.UpdatedBy = userNo;
                        locationEx.IsActive = 1;
                        locationEx.ProductId = item.ProductId;
                        updatedsEx.Add(locationEx);
                    }
                }
                #endregion
                #region 物料绑定
                if (item.Type == (int)InvStoreType.物料绑定)
                {
                    if (item.CurQty == 0 && item.ChkQty == 0)
                    {
                        if (stg == null)
                        {
                            stg = new InvStgEntity();
                            stg.Id = Guid.NewGuid().ToString();
                            stg.LocationId = item.LocationId;
                            stg.ProductId = item.ProductId;
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            addsStg.Add(stg);
                        }
                        else
                        {
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            updatesStg.Add(stg);
                        }
                        if (locationEx == null)
                        {
                            locationEx.Id = Guid.NewGuid().ToString();
                            locationEx.CreatedBy = userNo;
                            locationEx.CreatedDate = DateTime.Now;
                            locationEx.UpdatedDate = DateTime.Now;
                            locationEx.UpdatedBy = userNo;
                            locationEx.IsActive = 1;
                            locationEx.LocationId = item.LocationId;
                            locationEx.Type = (int)InvStoreType.物料绑定;
                            locationEx.ProductId = item.ProductId;
                            addsEx.Add(locationEx);
                        }
                    }
                    if (item.CurQty != 0 && item.ChkQty != 0 && item.CurQty != item.ChkQty)
                    {
                        stg.UpdatedDate = DateTime.Now;
                        stg.CurrentQty = item.ChkQty;
                        stg.IsFull = item.IsFull;
                        updatesStg.Add(stg);
                    }
                    if (item.CurQty != 0 && item.ChkQty == 0)
                    {
                        stg.UpdatedDate = DateTime.Now;
                        stg.CurrentQty = item.ChkQty;
                        stg.IsFull = item.IsFull;
                        updatesStg.Add(stg);
                    }
                    if (item.CurQty == 0 && item.ChkQty != 0)
                    {
                        if (stg == null)
                        {
                            stg = new InvStgEntity();
                            stg.Id = Guid.NewGuid().ToString();
                            stg.LocationId = item.LocationId;
                            stg.ProductId = item.ProductId;
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            addsStg.Add(stg);
                        }
                        else
                        {
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            updatesStg.Add(stg);
                        }
                        if (locationEx == null)
                        {
                            locationEx.Id = Guid.NewGuid().ToString();
                            locationEx.CreatedBy = userNo;
                            locationEx.CreatedDate = DateTime.Now;
                            locationEx.UpdatedDate = DateTime.Now;
                            locationEx.UpdatedBy = userNo;
                            locationEx.IsActive = 1;
                            locationEx.LocationId = item.LocationId;
                            locationEx.Type = (int)InvStoreType.物料绑定;
                            locationEx.ProductId = item.ProductId;
                            addsEx.Add(locationEx);
                        }
                    }
                }
                #endregion
                #region 按生产订单
                if (item.Type == (int)InvStoreType.按生产订单)
                {
                    if (item.CurQty == 0 && item.ChkQty == 0)
                    {
                        if (stg != null)
                        {
                            delsStg.Add(stg);
                        }
                        if (locationEx != null)
                        {
                            int count = DataAccess.Select<InvWhLocationExEntity>(new InvWhLocationExEntity { RelatedId = locationEx.RelatedId, Type = (int)InvStoreType.按生产订单, IsActive = 1 }).Count;
                            if (count > 1)
                            {
                                delsEx.Add(locationEx);
                            }
                            else if (count == 1)
                            {
                                locationEx.UpdatedDate = DateTime.Now;
                                locationEx.UpdatedBy = userNo;
                                locationEx.IsActive = 1;
                                locationEx.LocationId = item.LocationId;
                                locationEx.Type = (int)InvStoreType.通用;
                                locationEx.ProductId = null;
                                locationEx.RelatedId = null;
                                locationEx.LotNo = null;
                                updatedsEx.Add(locationEx);
                            }
                        }
                    }
                    if (item.CurQty != 0 && item.ChkQty != 0 && item.CurQty != item.ChkQty)
                    {
                        stg.UpdatedDate = DateTime.Now;
                        stg.CurrentQty = item.ChkQty;
                        stg.IsFull = item.IsFull;
                        updatesStg.Add(stg);
                    }
                    if (item.CurQty != 0 && item.ChkQty == 0)
                    {
                        int count = DataAccess.Select<InvWhLocationExEntity>(new InvWhLocationExEntity { RelatedId = locationEx.RelatedId, Type = (int)InvStoreType.按生产订单, IsActive = 1 }).Count;
                        if (count > 1)
                        {
                            delsEx.Add(locationEx);
                        }
                        else if (count == 1)
                        {
                            locationEx.UpdatedDate = DateTime.Now;
                            locationEx.UpdatedBy = userNo;
                            locationEx.IsActive = 1;
                            locationEx.LocationId = item.LocationId;
                            locationEx.Type = (int)InvStoreType.通用;
                            locationEx.ProductId = null;
                            locationEx.RelatedId = null;
                            locationEx.LotNo = null;
                            updatedsEx.Add(locationEx);
                        }
                        delsStg.Add(stg);
                    }
                    if (item.CurQty == 0 && item.ChkQty != 0)
                    {
                        if (stg == null)
                        {
                            stg = new InvStgEntity();
                            stg.Id = Guid.NewGuid().ToString();
                            stg.LocationId = item.LocationId;
                            stg.ProductId = item.ProductId;
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            addsStg.Add(stg);
                        }
                        else
                        {
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            updatesStg.Add(stg);
                        }
                        if (locationEx == null)
                        {
                            locationEx.Id = Guid.NewGuid().ToString();
                            locationEx.CreatedBy = userNo;
                            locationEx.CreatedDate = DateTime.Now;
                            locationEx.UpdatedDate = DateTime.Now;
                            locationEx.UpdatedBy = userNo;
                            locationEx.IsActive = 1;
                            locationEx.LocationId = item.LocationId;
                            locationEx.Type = (int)InvStoreType.物料绑定;
                            locationEx.ProductId = item.ProductId;
                            locationEx.RelatedId = item.RelatedId;
                            addsEx.Add(locationEx);
                        }
                    }
                }
                #endregion
                #region 按采购到货
                if (item.Type == (int)InvStoreType.按采购到货 || item.Type == (int)InvStoreType.自定义)
                {
                    if (item.CurQty != 0 && item.ChkQty != 0 && item.CurQty != item.ChkQty)
                    {
                        stg.UpdatedDate = DateTime.Now;
                        stg.CurrentQty = item.ChkQty;
                        stg.IsFull = item.IsFull;
                        updatesStg.Add(stg);
                    }
                    if (item.CurQty != 0 && item.ChkQty == 0)
                    {
                        delsStg.Add(stg);
                        delsEx.Add(locationEx);
                    }
                    if (item.CurQty == 0 && item.ChkQty != 0)
                    {
                        if (stg == null)
                        {
                            stg = new InvStgEntity();
                            stg.Id = Guid.NewGuid().ToString();
                            stg.LocationId = item.LocationId;
                            stg.ProductId = item.ProductId;
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            addsStg.Add(stg);
                        }
                        else
                        {
                            stg.CurrentQty = item.CurQty;
                            stg.UpdatedDate = DateTime.Now;
                            stg.IsFull = item.IsFull;
                            updatesStg.Add(stg);
                        }
                        if (locationEx == null)
                        {
                            locationEx.Id = Guid.NewGuid().ToString();
                            locationEx.CreatedBy = userNo;
                            locationEx.CreatedDate = DateTime.Now;
                            locationEx.UpdatedDate = DateTime.Now;
                            locationEx.UpdatedBy = userNo;
                            locationEx.IsActive = 1;
                            locationEx.LocationId = item.LocationId;
                            locationEx.Type = item.Type;
                            locationEx.ProductId = item.ProductId;
                            locationEx.RelatedId = item.RelatedId;
                            locationEx.LotNo = item.LotNo;
                            addsEx.Add(locationEx);
                        }
                    }
                }
                #endregion

                var stgHis = new InvStgHisEntity();
                stgHis.Id = Guid.NewGuid().ToString();
                stgHis.CreatedBy = userNo;
                stgHis.CreatedDate = DateTime.Now;
                stgHis.ProductId = item.ProductId;
                stgHis.RelatedId = item.RelatedId;
                stgHis.Type = 1;
                if (item.DiffQty > 0)
                    stgHis.QtyIn = item.DiffQty;
                else if (item.DiffQty < 0)
                    stgHis.QtyOut = -item.DiffQty;
                else
                {
                    stgHis.QtyIn = 0;
                    stgHis.QtyOut = 0;
                }
                addsStgHis.Add(stgHis);

            }
            capp.Status = WfStatus.WFS30.ToString();
            co.Status = WfStatus.WFS30.ToString();
            if (wh.IsLock == 1)
                wh.IsLock = 0;
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Insert(addsStg, broker);
                    DataAccess.Insert(addsEx, broker);
                    DataAccess.Update(updatesStg, broker);
                    DataAccess.Update(updatedsEx, broker);
                    DataAccess.Delete(delsStg, broker);
                    DataAccess.Delete(delsEx, broker);
                    DataAccess.Insert(addsStgHis, broker);
                    DataAccess.Update(capp, broker);
                    DataAccess.Update(co, broker);
                    DataAccess.Update(wh, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return -1;
                }
            }
        }

        #endregion

        //出库申请-出库单
        //出库申请单状态更新为：WFS30
        public InvMaintainOo InvOAppToOo(string userNo, InvOappEntity app, List<InvOAppItemDto> items)
        {
            if (app == null)
                return null;
            if (items == null)
                return null;
            if (items.Count == 0)
                return null;
            var oo = new InvOoEntity();
            oo.Id = Guid.NewGuid().ToString();
            oo.CreatedBy = userNo;
            oo.CreatedDate = DateTime.Now;
            oo.UpdatedBy = userNo;
            oo.UpdatedDate = DateTime.Now;
            oo.IsActive = 1;
            oo.OappId = app.Id;
            oo.OappNo = app.AppNo;
            oo.OoNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutOrder");
            oo.RelatedId = app.RelatedId;
            oo.RelatedNo = app.RelatedNo;
            oo.Type = app.Type;
            oo.Remark = app.Remark;
            oo.Status = Common.WfStatus.WFS10.ToString();

            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));
            var moo = new InvMaintainOo();
            moo.Id = oo.Id;
            moo.CreatedBy = oo.UpdatedBy;
            moo.CreatedDate = oo.UpdatedDate;
            if (!string.IsNullOrEmpty(oo.UpdatedBy))
            {
                var createdUser = ps.getUser(null, oo.UpdatedBy);
                moo.CreatedUser = createdUser.firstName;
            }
            moo.UpdatedBy = oo.UpdatedBy;
            moo.UpdatedDate = oo.UpdatedDate;
            if (!string.IsNullOrEmpty(oo.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, oo.UpdatedBy);
                moo.UpdatedUser = updatedUser.firstName;
            }
            moo.IsActive = 1;
            moo.OoNo = oo.OoNo;
            moo.RelatedId = oo.RelatedId;
            moo.Remark = oo.Remark;
            moo.Status = oo.Status;

            List<InvOoiEntity> oois = new List<InvOoiEntity>();
            foreach (var item in items)
            {
                var ooi = new InvOoiEntity();
                ooi.Id = Guid.NewGuid().ToString();
                ooi.OoId = oo.Id;
                ooi.ProductId = item.ProductId;
                ooi.Qty = item.Qty;
                oois.Add(ooi);
            }

            app.UpdatedBy = userNo;
            app.UpdatedDate = DateTime.Now;
            app.Status = WfStatus.WFS30.ToString();

            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Update(app, broker);
                    DataAccess.Insert(oo, broker);
                    DataAccess.Insert(oois, broker);
                    broker.Commit();
                    return moo;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    throw ex;
                }
            }

        }

        #region 出库

        //出库申请
        public int? AddInvOapp(string userNo, InvOappEntity app)
        {
            if (app == null)
                return 1;
            app.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutAppOrder");
            app.CreatedBy = userNo;
            app.CreatedDate = DateTime.Now;
            app.UpdatedBy = userNo;
            app.UpdatedDate = DateTime.Now;
            if (DataAccess.Insert(app))
                return null;
            else return 2;
        }

        public int? UpdateInvOapp(string userNo, InvOappEntity app)
        {
            if (app == null)
                return 1;
            app.UpdatedBy = userNo;
            app.UpdatedDate = DateTime.Now;
            if (DataAccess.Update(app))
                return null;
            else return 2;
        }

        public int? DelInvOapp(InvOappEntity app)
        {
            if (app == null)
                return 1;
            List<InvOappiEntity> items = DataAccess.Select<InvOappiEntity>(new InvOappiEntity { OoAppId = app.Id });
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    if (items != null)
                    {
                        DataAccess.Delete(items, broker);
                    }
                    DataAccess.Delete(app, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 2;
                }
            }
        }

        public int? SaveInvOapp(InvOAppSaveParam param)
        {
            if (param == null)
                return 1;
            if (param.Oapp == null)
                return 2;
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvOappEntity cur = DataAccess.SelectSingle<InvOappEntity>(new InvOappEntity { Id = param.Oapp.Id });
                    if (cur == null)//新增
                    {
                        param.Oapp.CreatedDate = DateTime.Now;
                        param.Oapp.UpdatedDate = DateTime.Now;
                        param.Oapp.CreatedBy = param.CurUserNo;
                        param.Oapp.UpdatedBy = param.CurUserNo;
                        param.Oapp.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutAppOrder");
                        foreach (var item in param.AddItems)
                        {
                            item.OoAppId = param.Oapp.Id;
                        }
                        List<InvOappiEntity> oappItems = new List<InvOappiEntity>();
                        foreach (var addItemDto in param.AddItems)
                        {
                            Mapper.CreateMap<InvOAppItemDto, InvOappiEntity>();
                            var oappItem = AutoMapper.Mapper.Map<InvOAppItemDto, InvOappiEntity>(addItemDto);
                            oappItems.Add(oappItem);
                        }

                        broker.BeginTransaction();
                        DataAccess.Insert(param.Oapp, broker);
                        DataAccess.Insert(oappItems, broker);
                        broker.Commit();
                        return null;
                    }
                    else//修改
                    {
                        param.Oapp.UpdatedDate = DateTime.Now;
                        param.Oapp.UpdatedBy = param.CurUserNo;
                        foreach (var item in param.AddItems)
                        {
                            item.OoAppId = param.Oapp.Id;
                        }
                        List<InvOappiEntity> delItems = new List<InvOappiEntity>();
                        foreach (var delItemDto in param.DelItems)
                        {
                            Mapper.CreateMap<InvOAppItemDto, InvOappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvOAppItemDto, InvOappiEntity>(delItemDto);
                            delItems.Add(item);
                        }
                        List<InvOappiEntity> updatedItems = new List<InvOappiEntity>();
                        foreach (var updatedItemDto in param.UpdatedItems)
                        {
                            Mapper.CreateMap<InvOAppItemDto, InvOappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvOAppItemDto, InvOappiEntity>(updatedItemDto);
                            updatedItems.Add(item);
                        }
                        List<InvOappiEntity> addItems = new List<InvOappiEntity>();
                        foreach (var addItemDto in param.AddItems)
                        {
                            Mapper.CreateMap<InvOAppItemDto, InvOappiEntity>();
                            var item = AutoMapper.Mapper.Map<InvOAppItemDto, InvOappiEntity>(addItemDto);
                            addItems.Add(item);
                        }

                        broker.BeginTransaction();
                        DataAccess.Update(param.Oapp, broker);
                        DataAccess.Delete(delItems, broker);
                        DataAccess.Update(updatedItems, broker);
                        DataAccess.Insert(addItems, broker);
                        broker.Commit();
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 3;
                }
            }
        }

        public InvOappEntity GetInvOappByKey(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            return DataAccess.SelectSingle<InvOappEntity>(new InvOappEntity { Id = id });
        }

        public InvMaintainOApp GetInvMaintainOAppByKey(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            var app = InvOappBs.GetInvOapp(new InvOappEntity { Id = appId });
            if (app == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            var mapp = new InvMaintainOApp();
            mapp.Id = app.Id;
            mapp.CreatedBy = app.CreatedBy;
            if (!string.IsNullOrEmpty(app.CreatedBy))
            {
                var createdUser = ps.getUser(null, app.CreatedBy);
                mapp.CreatedUser = createdUser.firstName;
            }
            mapp.CreatedDate = app.CreatedDate;
            mapp.UpdatedBy = app.UpdatedBy;
            if (!string.IsNullOrEmpty(app.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, app.UpdatedBy);
                mapp.UpdatedUser = updatedUser.firstName;
            }
            mapp.UpdatedDate = app.UpdatedDate;
            mapp.IsActive = app.IsActive;
            mapp.AppNo = app.AppNo;
            mapp.Type = app.Type;
            mapp.RelatedId = app.RelatedId;
            if (!string.IsNullOrEmpty(app.RelatedId))
            {
                switch (app.Type)
                {
                    case 10:
                        //var wo = ProdWoBs.GetProdWo(new ProdWoEntity { Id = app.RelatedId });
                        //if (wo == null)
                        //    return null;
                        mapp.RelatedNo = app.RelatedId;
                        break;
                    case 20:
                        var po = PurPoBs.GetPurPo(new PurPoEntity { Id = app.RelatedId });
                        if (po == null)
                            return null;
                        mapp.RelatedNo = po.PoNo;
                        break;
                    case 30:

                        break;
                    case 40:

                        break;
                    default:
                        return null;
                }
            }
            mapp.Remark = app.Remark;
            mapp.Status = app.Status;
            return mapp;

        }

        public System.Data.DataSet GetInvOAppAllDsByCondition(InvOAppQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.CreatedBy))
            {
                condition += " and app.CREATED_BY='" + con.CreatedBy + "'";
            }
            else if (!string.IsNullOrEmpty(con.CreatedUser))
            {
                condition += " and u1.firstName like '%" + con.CreatedUser + "%'";
            }
            if (con.IsActive != null)
            {
                condition += " and app.IS_ACTIVE=" + con.IsActive;
            }
            if (!string.IsNullOrEmpty(con.AppNo))
            {
                condition += " and app.APP_NO='" + con.AppNo + "'";
            }
            if (con.Type != null)
            {
                condition += " and app.TYPE=" + con.Type;
            }
            if (!string.IsNullOrEmpty(con.RelatedId))
            {
                condition += " and app.RELATED_ID='" + con.RelatedId + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and app.STATUS='" + con.Status + "'";
            }

            return InvOappBs.GetAllDsByCondition(pageIndex, pageSize, condition);
        }

        //出库申请单明细
        public List<InvOAppItemDto> GetInvOAppItemDtoAllListByAppId(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            List<InvOappiEntity> items = DataAccess.Select<InvOappiEntity>(new InvOappiEntity { OoAppId = appId });
            List<InvOAppItemDto> dtos = new List<InvOAppItemDto>();
            if (items != null)
            {
                foreach (var item in items)
                {
                    Mapper.CreateMap<InvOappiEntity, InvOAppItemDto>();
                    var dto = AutoMapper.Mapper.Map<InvOappiEntity, InvOAppItemDto>(item);
                    MstProductEntity material = DataAccess.SelectSingle<MstProductEntity>(new MstProductEntity { ProductId = item.ProductId });
                    if (material != null)
                    {
                        dto.ProductName = material.ProductName;
                        dto.ProductCode = material.ProductCode;
                        dto.Unit = material.Unit;
                        var curStgQty = DataAccess.Select<InvStgEntity>(new InvStgEntity { ProductId = material.ProductId }).Sum(a => a.CurrentQty);
                        dto.CurStgQty = curStgQty;

                    }
                    dtos.Add(dto);
                }
                return dtos;
            }
            else return null;
        }

        public System.Data.DataSet GetInvOAppiAllDsByAppId(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return null;
            string sql = @"select * from INV_OAPPI where OO_APP_ID='{0}'";
            sql = string.Format(sql, appId);
            return InvOappiBs.GetAllDsBySql(sql);
        }

        public int? DelInvOAppiEntity(InvOappiEntity appi)
        {
            if (appi == null)
                return 1;
            if (InvOappiBs.DeleteInvOappi(appi))
                return null;
            else return -1;
        }

        public int? SaveInvOAppi(InvOappiEntity appi)
        {
            if (appi == null)
                return null;
            InvOappiEntity oappi = InvOappiBs.GetInvOappi(new InvOappiEntity { Id = appi.Id });
            if (oappi == null)
            {
                if (InvOappiBs.InsertInvOappi(oappi))
                    return null;
                else return -1;
            }
            else
            {
                oappi.ProductId = appi.ProductId;
                oappi.Qty = appi.Qty;
                oappi.OoAppId = appi.OoAppId;
                if (InvOappiBs.UpdateInvOappi(oappi))
                    return null;
                else return -1;
            }

        }

        public int? SaveInvOAppis(System.Data.DataSet appi)
        {
            if (appi == null)
                return 1;
            if (appi.Tables[0].Rows.Count == 0)
                return 2;
            List<InvOappiEntity> updates = new List<InvOappiEntity>();
            foreach (DataRow dr in appi.Tables[0].Rows)
            {
                if (dr.RowState == DataRowState.Modified)
                {
                    var oappi = new InvOappiEntity(dr);
                    updates.Add(oappi);
                }
            }
            if (InvOappiBs.UpdateInvOappi(updates))
                return null;
            else return -1;
        }

        //出库单
        public int? AddInvOo(string userNo, InvOoEntity oo)
        {
            if (oo == null)
                return 1;
            oo.OoNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutOrder");
            oo.CreatedBy = userNo;
            oo.CreatedDate = DateTime.Now;
            oo.UpdatedBy = userNo;
            oo.UpdatedDate = DateTime.Now;
            if (DataAccess.Insert(oo))
                return null;
            else return 2;
        }

        public int? UpdateInvOo(string userNo, InvOoEntity oo)
        {
            if (oo == null)
                return 1;
            oo.UpdatedBy = userNo;
            oo.UpdatedDate = DateTime.Now;
            if (DataAccess.Update(oo))
                return null;
            else return 2;
        }

        public int? DelInvOo(InvOoEntity oo)
        {
            if (oo == null)
                return 1;
            List<InvOoiEntity> ooItems = DataAccess.Select<InvOoiEntity>(new InvOoiEntity { OoId = oo.Id });
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    if (ooItems != null)
                    {

                        DataAccess.Delete(ooItems, broker);
                    }
                    DataAccess.Delete(oo, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 2;
                }
            }
        }

        public int? DelInvOoDto(InvOoDto dto)
        {
            if (dto == null)
                return 1;
            InvOoEntity oo = DataAccess.SelectSingle<InvOoEntity>(new InvOoEntity { Id = dto.Id });
            List<InvOoiEntity> ooItems = DataAccess.Select<InvOoiEntity>(new InvOoiEntity { OoId = dto.Id });
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    if (ooItems != null)
                    {

                        DataAccess.Delete(ooItems, broker);
                    }
                    DataAccess.Delete(oo, broker);
                    broker.Commit();
                    return null;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 2;
                }
            }
        }

        //保存出库单
        public int? SaveInvOo(InvOoSaveParam param)
        {
            if (param == null)
                return 1;
            if (param.Oo == null)
                return 2;
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvOoEntity cur = DataAccess.SelectSingle<InvOoEntity>(new InvOoEntity { Id = param.Oo.Id });
                    if (cur == null)//新增
                    {
                        param.Oo.CreatedDate = DateTime.Now;
                        param.Oo.UpdatedDate = DateTime.Now;
                        param.Oo.CreatedBy = param.CurUserNo;
                        param.Oo.UpdatedBy = param.CurUserNo;
                        param.Oo.OoNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutOrder");
                        foreach (var item in param.AddItems)
                        {
                            item.OoId = param.Oo.Id;
                        }
                        List<InvOoiEntity> ooItems = new List<InvOoiEntity>();
                        foreach (var addItemDto in param.AddItems)
                        {
                            Mapper.CreateMap<InvOoItemDto, InvOoiEntity>();
                            var ooItem = AutoMapper.Mapper.Map<InvOoItemDto, InvOoiEntity>(addItemDto);
                            ooItems.Add(ooItem);
                        }

                        broker.BeginTransaction();
                        DataAccess.Insert(param.Oo, broker);
                        DataAccess.Insert(ooItems, broker);
                        broker.Commit();
                        return null;
                    }
                    else//修改
                    {
                        param.Oo.UpdatedDate = DateTime.Now;
                        param.Oo.UpdatedBy = param.CurUserNo;
                        foreach (var item in param.AddItems)
                        {
                            item.OoId = param.Oo.Id;
                        }
                        List<InvOoiEntity> delItems = new List<InvOoiEntity>();
                        foreach (var delItemDto in param.DelItems)
                        {
                            Mapper.CreateMap<InvOoItemDto, InvOoiEntity>();
                            var ooItem = AutoMapper.Mapper.Map<InvOoItemDto, InvOoiEntity>(delItemDto);
                            delItems.Add(ooItem);
                        }
                        List<InvOoiEntity> updatedItems = new List<InvOoiEntity>();
                        foreach (var updatedItemDto in param.UpdatedItems)
                        {
                            Mapper.CreateMap<InvOoItemDto, InvOoiEntity>();
                            var ooItem = AutoMapper.Mapper.Map<InvOoItemDto, InvOoiEntity>(updatedItemDto);
                            updatedItems.Add(ooItem);
                        }
                        List<InvOoiEntity> addItems = new List<InvOoiEntity>();
                        foreach (var addItemDto in param.AddItems)
                        {
                            Mapper.CreateMap<InvOoItemDto, InvOoiEntity>();
                            var ooItem = AutoMapper.Mapper.Map<InvOoItemDto, InvOoiEntity>(addItemDto);
                            addItems.Add(ooItem);
                        }

                        broker.BeginTransaction();
                        DataAccess.Update(param.Oo, broker);
                        DataAccess.Delete(delItems, broker);
                        DataAccess.Update(updatedItems, broker);
                        DataAccess.Insert(addItems, broker);
                        broker.Commit();
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return 3;
                }
            }
        }

        //public int? SaveInvOois(System.Data.DataSet ooi)
        //{
        //    throw new NotImplementedException();
        //}

        public InvOoEntity GetInvOoByKey(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            return DataAccess.SelectSingle<InvOoEntity>(new InvOoEntity { Id = id });

        }

        public DataSet GetInvOoAllDsByCondition(InvOoQueryCondition con)
        {
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.CreatedBy))
            {
                condition += " and oo.CREATED_BY='" + con.CreatedBy + "'";
            }
            else if (!string.IsNullOrEmpty(con.CreatedUser))
            {
                condition += " and u1.firstName like '%" + con.CreatedUser + "%'";
            }
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and oo.WH_ID='" + con.WhId + "'";
            }
            if (con.IsActive != null)
            {
                condition += " and oo.IS_ACTIVE=" + con.IsActive;
            }
            if (!string.IsNullOrEmpty(con.OoNo))
            {
                condition += " and oo.IO_NO='" + con.OoNo + "'";
            }
            if (con.Type != null && con.Type > 0)
            {
                condition += " and oo.TYPE=" + con.Type;
            }
            if (!string.IsNullOrEmpty(con.RelatedId))
            {
                condition += " and oo.RELATED_ID='" + con.RelatedId + "'";
            }
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and oo.STATUS='" + con.Status + "'";
            }

            return InvOoBs.GetInvOoAllDsByCondition(pageIndex, pageSize, condition);
        }

        public InvOoPageResult GetInvOoAllListByCondition(InvOoQueryCondition con)
        {
            if (con == null)
                return null;
            int pageIndex = 1;
            int pageSize = 50;
            if (con.txtPageIndex != 0)
                pageIndex = con.txtPageIndex;
            if (con.txtPageSize != 0)
                pageSize = con.txtPageSize;
            string condition = "";
            if (!string.IsNullOrEmpty(con.OoNo))
            {
                condition += " and oo.OO_NO='" + con.OoNo + "'";
            }
            if (!string.IsNullOrEmpty(con.WhId))
            {
                condition += " and oo.WH_ID='" + con.WhId + "'";
            }
            if (con.Type != 0)
            {
                condition += " and oo.TYPE='" + con.Type + "'";
            }
            if (!string.IsNullOrEmpty(con.RelatedId))
            {
                condition += " and oo.RELATED_ID='" + con.RelatedId + "'";
            }
            condition += " and oo.IS_ACTIVE=" + con.IsActive;
            if (!string.IsNullOrEmpty(con.Status))
            {
                condition += " and oo.STATUS='" + con.Status + "'";
            }
            if (!string.IsNullOrEmpty(con.OappUserNo))
            {
                condition += " and app.CREATED_BY='" + con.OappUserNo + "'";
            }
            else if (!string.IsNullOrEmpty(con.OappUserName))
            {
                condition += " and u3.firstName='" + con.OappUserName + "'";
            }
            string sql = "";
            if (string.IsNullOrEmpty(condition))
            {
                string sqlSource = @"select top {0} *,(select count(1) from INV_OO) as cnt
from INV_OO
where id not in (
    select top ({1}*({2}-1)) id from INV_OO order by created_date desc
) order by created_date desc";
                sqlSource = string.Format(sqlSource, pageSize, pageSize, pageIndex);
                sql = @"select oo.*,u1.firstName as CREATED_USER,u2.firstName as UPDATED_USER,
u3.firstName as APP_USER_NAME,u3.userNo as APP_USER_NO 
from ({0}) oo
left join INV_OAPP app on oo.OAPP_ID=app.ID
left join BPMDB.dbo.PW_User u1 on oo.CREATED_BY=u1.userNo
left join BPMDB.dbo.PW_User u2 on oo.CREATED_BY=u2.userNo
left join BPMDB.dbo.PW_User u3 on app.CREATED_BY=u3.userNo";
                sql = string.Format(sql, sqlSource);
            }
            else
            {
                sql = @"select top {0} *,(select count(1) from ({3}) t) as cnt
from ({3}) t
where t.id not in (
    select top ({1}*({2}-1)) id from ({3}) t order by created_date desc
) order by created_date desc";
                string sqlSource = @"select oo.*,u1.firstName as CREATED_USER,u2.firstName as UPDATED_USER,
u3.firstName as APP_USER_NAME,u3.userNo as APP_USER_NO 
from INV_OO oo
left join INV_OAPP app on oo.OAPP_ID=app.ID
left join BPMDB.dbo.PW_User u1 on oo.CREATED_BY=u1.userNo
left join BPMDB.dbo.PW_User u2 on oo.CREATED_BY=u2.userNo
left join BPMDB.dbo.PW_User u3 on app.CREATED_BY=u3.userNo
where 1=1 ";
                sqlSource += condition;
                sql = string.Format(sql, pageSize, pageSize, pageIndex, sqlSource);
            }
            DataSet ds = DataAccess.SelectDataSet(sql);
            if (ds == null)
                return null;
            InvOoPageResult result = new InvOoPageResult();
            if (ds.Tables[0].Rows.Count == 0)
            {
                result.OutOrders = null;
                result.TotalCount = 0;
                return result;
            }
            List<InvOoDto> outOrdersDto = new List<InvOoDto>();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                InvOoEntity oo = new InvOoEntity(dr);
                Mapper.CreateMap<InvOoEntity, InvOoDto>();
                var ooDto = AutoMapper.Mapper.Map<InvOoEntity, InvOoDto>(oo);
                if (dr["APP_USER_NAME"] != DBNull.Value)
                    ooDto.AppUserName = dr["APP_USER_NAME"].ToString();
                if (dr["APP_USER_NO"] != DBNull.Value)
                    ooDto.AppUserNo = dr["APP_USER_NO"].ToString();
                if (dr["APP_USER_NAME"] != DBNull.Value && dr["APP_USER_NO"] != DBNull.Value)
                    ooDto.AppUser = ooDto.AppUserName + "(" + ooDto.AppUserNo + ")";
                outOrdersDto.Add(ooDto);
            }
            result.OutOrders = outOrdersDto;
            result.TotalCount = (int)ds.Tables[0].Rows[0]["cnt"];
            return result;

        }

        public List<InvMaintainOoi> GetInvOoiAllListByOoId(string ooId)
        {
            if (string.IsNullOrEmpty(ooId))
                return null;
            string sql = @"Select ooi.*,mp.PRODUCT_NAME,mp.PRODUCT_CODE,loc.STAND,loc.LOCATION,loc.VOLUME,loc.AREA,loc.IS_SINGLE 
from INV_OOI ooi
left join MST_PRODUCT mp on ooi.PRODUCT_ID=mp.PRODUCT_ID
left join INV_WH_LOCATION loc on ooi.LOCATION_ID=loc.ID
where ooi.OO_ID='{0}'";
            sql = string.Format(sql, ooId);
            DataSet ds = InvIoBs.GetAllDsBySql(sql);
            if (ds == null)
                return null;
            if (ds.Tables[0].Rows.Count == 0)
                return null;
            var results = new List<InvMaintainOoi>();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                var r = new InvMaintainOoi();
                r.Id = dr["ID"].ToString();
                r.OoId = dr["OO_ID"].ToString();
                r.ProductId = dr["PRODUCT_ID"].ToString();
                r.ProductName = dr["PRODUCT_NAME"].ToString();
                r.ProductCode = dr["PRODUCT_CODE"].ToString();
                r.Qty = Convert.ToDecimal(dr["QTY"].ToString());
                r.Remark = dr["REMARK"].ToString();
                r.LocationId = dr["LOCATION_ID"].ToString();
                r.Unit = dr["UNIT"].ToString();
                r.Stand = dr["STAND"].ToString();
                r.LocationNo = dr["LOCATION"].ToString();
                if (dr["VOLUME"].ToString() != "")
                    r.Volume = Convert.ToDecimal(dr["VOLUME"].ToString());
                if (dr["Area"].ToString() != "")
                    r.Area = Convert.ToDecimal(dr["Area"].ToString());
                if (dr["IS_SINGLE"].ToString() != "")
                    r.IsSingle = Convert.ToInt32(dr["IS_SINGLE"].ToString());
                results.Add(r);
            }
            return results;

        }

        public DataSet GetAllDsByOoId(string ooId)
        {

            if (string.IsNullOrEmpty(ooId))
                return null;
            string sql = @"select ooi.*,loc.STAND,loc.LOCATION,loc.VOLUME,loc.AREA,loc.IS_SINGLE 
from INV_OOI ooi
left join INV_WH_LOCATION loc on ooi.LOCATION_ID=loc.ID
where ooi.OO_ID='{0}'";
            sql = string.Format(sql, ooId);
            return InvOoBs.GetAllDsByOoId(sql);
        }

        public InvMaintainOo GetInvMaintainOoByKey(string ooId)
        {
            if (string.IsNullOrEmpty(ooId))
                return null;
            var io = InvOoBs.GetInvOo(new InvOoEntity { Id = ooId });
            if (io == null)
                return null;
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

            var mio = new InvMaintainOo();
            mio.Id = io.Id;
            mio.CreatedBy = io.CreatedBy;
            if (!string.IsNullOrEmpty(io.CreatedBy))
            {
                var createdUser = ps.getUser(null, io.CreatedBy);
                mio.CreatedUser = createdUser.firstName;
            }
            mio.CreatedDate = io.CreatedDate;
            mio.UpdatedBy = io.UpdatedBy;
            if (!string.IsNullOrEmpty(io.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, io.UpdatedBy);
                mio.UpdatedUser = updatedUser.firstName;
            }
            mio.UpdatedDate = io.UpdatedDate;
            mio.IsActive = io.IsActive;
            mio.WhId = io.WhId;
            mio.OoNo = io.OoNo;
            mio.Type = io.Type;
            mio.RelatedId = io.RelatedId;
            if (!string.IsNullOrEmpty(io.RelatedId))
            {
                switch (io.Type)
                {
                    case 10:
                        mio.RelatedNo = io.RelatedId;
                        break;
                    case 20:
                        var po = PurPoBs.GetPurPo(new PurPoEntity { Id = io.RelatedId });
                        if (po == null)
                            return null;
                        mio.RelatedNo = po.PoNo;
                        break;
                    case 30:

                        break;
                    case 40:

                        break;
                    default:
                        return null;
                }
            }
            mio.Remark = io.Remark;
            mio.Status = io.Status;
            return mio;
        }

        //出库结算，扣库存，
        public string InvOutput(InvMaintainOo oo, List<InvMaintainOoi> oois)
        {
            try
            {
                bool result = InvOoBs.InvOutput(oo, oois);
                if (result)
                    return "";
                else
                    return "出库失败";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        //出库单明细
        public List<InvOoItemDto> GetInvOoItemDtoAllListByOoId(string ooId)
        {
            if (string.IsNullOrEmpty(ooId))
                return null;
            var ooItems = DataAccess.Select<InvOoiEntity>(new InvOoiEntity { OoId = ooId });
            if (ooItems != null)
            {
                List<InvOoItemDto> ooItemsDto = new List<InvOoItemDto>();
                foreach (var ooItem in ooItems)
                {
                    Mapper.CreateMap<InvOoiEntity, InvOoItemDto>();
                    var ooItemDto = AutoMapper.Mapper.Map<InvOoiEntity, InvOoItemDto>(ooItem);

                    var material = DataAccess.SelectSingle<MstProductEntity>(new MstProductEntity { ProductId = ooItem.ProductId });
                    if (material != null)
                    {
                        ooItemDto.ProductName = material.ProductName;
                        ooItemDto.ProductCode = material.ProductCode;
                        ooItemDto.Unit = material.Unit;
                    }
                    if (!string.IsNullOrEmpty(ooItem.WhId))
                    {
                        var wh = DataAccess.SelectSingle<InvWhEntity>(new InvWhEntity { Id = ooItem.WhId });
                        if (wh != null)
                        {
                            ooItemDto.WhName = wh.WhName;
                        }
                    }
                    if (!string.IsNullOrEmpty(ooItem.LocationId))
                    {
                        var loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = ooItem.LocationId });
                        if (loc != null)
                        {
                            ooItemDto.Stand = loc.Stand;
                            ooItemDto.LocationName = loc.Location;
                        }
                    }
                    decimal curStgQty = DataAccess.Select<InvStgEntity>(new InvStgEntity { ProductId = ooItem.ProductId }).Sum(a => a.CurrentQty);
                    ooItemDto.CurStgQty = curStgQty;

                    ooItemsDto.Add(ooItemDto);
                }
                return ooItemsDto;
            }
            else
            {
                return null;
            }
        }

        //自动分配出库库位
        public List<InvOoItemDto> AutoAssignOutLocation(InvAutoAssignOutLocationParam param)
        {
            List<InvOoItemDto> results = new List<InvOoItemDto>();
            foreach (var itemDto in param.ItemsDto)
            {
                if (itemDto.InvStoreType == (int)InvStoreType.物料绑定)
                {
                    InvOoItemDto result = itemDto;
                    var exList = InvWhLocationExBs.GetInvWhLocationExAllListByBind(itemDto.WhId, itemDto.ProductId, itemDto.Qty);
                    if (exList.Count > 0)
                    {
                        InvWhLocationEntity loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = exList[0].LocationId });
                        if (loc != null)
                        {
                            result.LocationId = loc.Id;
                            result.LocationName = loc.Location;
                            result.Stand = loc.Stand;
                        }
                    }
                    results.Add(result);
                }
                else if (itemDto.InvStoreType == (int)InvStoreType.按生产订单)
                {
                    InvOoItemDto result = itemDto;
                    var exList = InvWhLocationExBs.GetInvWhLocationExAllListBySo(itemDto.WhId, itemDto.ProductId, param.RelatedId, itemDto.Qty);
                    if (exList.Count > 0)
                    {
                        InvWhLocationEntity loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = exList[0].LocationId });
                        if (loc != null)
                        {
                            result.LocationId = loc.Id;
                            result.LocationName = loc.Location;
                            result.Stand = loc.Stand;
                        }
                    }
                    results.Add(result);
                }
                else if (itemDto.InvStoreType == (int)InvStoreType.按采购到货)
                {
                    InvOoItemDto result = itemDto;
                    var exList = InvWhLocationExBs.GetInvWhLocationExAllListByPcs(itemDto.WhId, itemDto.ProductId, param.RelatedId, itemDto.LotNo, itemDto.Qty);
                    if (exList.Count > 0)
                    {
                        InvWhLocationEntity loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = exList[0].LocationId });
                        if (loc != null)
                        {
                            result.LocationId = loc.Id;
                            result.LocationName = loc.Location;
                            result.Stand = loc.Stand;
                        }
                    }
                    results.Add(result);
                }
                else if (itemDto.InvStoreType == (int)InvStoreType.按工单任务)
                {
                }
                else if (itemDto.InvStoreType == (int)InvStoreType.自定义)
                {
                    InvOoItemDto result = itemDto;
                    var exList = InvWhLocationExBs.GetInvWhLocationExAllListByCustom(itemDto.WhId, itemDto.ProductId, itemDto.Qty);
                    if (exList.Count > 0)
                    {
                        InvWhLocationEntity loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = exList[0].LocationId });
                        if (loc != null)
                        {
                            result.LocationId = loc.Id;
                            result.LocationName = loc.Location;
                            result.Stand = loc.Stand;
                        }
                    }
                    results.Add(result);
                }
                else
                {
                    InvOoItemDto result = itemDto;
                    var exList = InvWhLocationExBs.GetInvWhLocationExAllListByCommon(itemDto.WhId, itemDto.ProductId, itemDto.Qty);
                    if (exList.Count > 0)
                    {

                        InvWhLocationEntity loc = DataAccess.SelectSingle<InvWhLocationEntity>(new InvWhLocationEntity { Id = exList[0].LocationId });
                        if (loc != null)
                        {
                            result.LocationId = loc.Id;
                            result.LocationName = loc.Location;
                            result.Stand = loc.Stand;
                        }
                    }
                    results.Add(result);
                }

            }
            return results;
        }

        //出库
        public InvStockOutResultMessage StockOut(string userNo, List<InvOoItemDto> itemsDto)
        {
            if (string.IsNullOrEmpty(userNo))
                return new InvStockOutResultMessage { Result = false, Message = "userNo为空" };
            if (itemsDto == null || itemsDto.Count == 0)
                return new InvStockOutResultMessage { Result = false, Message = "items为空" };
            var oo = DataAccess.SelectSingle<InvOoEntity>(new InvOoEntity { Id = itemsDto[0].OoId });
            if (oo == null)
                return new InvStockOutResultMessage { Result = false, Message = "出库单错误不存在" };
            var oapp = DataAccess.SelectSingle<InvOappEntity>(new InvOappEntity { Id = oo.OappId });
            if (oapp == null)
                return new InvStockOutResultMessage { Result = false, Message = "出库申请单错误不存在" };

            List<InvStgEntity> updateStg = new List<InvStgEntity>();
            List<InvStgEntity> delStg = new List<InvStgEntity>();
            List<InvStgHisEntity> addStgHis = new List<InvStgHisEntity>();
            List<InvWhLocationExEntity> updateEx = new List<InvWhLocationExEntity>();
            List<InvWhLocationExEntity> delEx = new List<InvWhLocationExEntity>();

            foreach (var item in itemsDto)
            {
                //更新库存表及历史明细
                var stg = DataAccess.SelectSingle<InvStgEntity>(new InvStgEntity { LocationId = item.LocationId, ProductId = item.ProductId });
                if (stg != null)
                {
                    stg.CurrentQty = stg.CurrentQty - item.Qty;
                    if (stg.CurrentQty == 0)
                    {
                        if (item.InvStoreType == (int)InvStoreType.通用)
                        {
                            delStg.Add(stg);
                            var ex = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity
                            {
                                LocationId = item.LocationId,
                                ProductId = item.ProductId,
                                Type = (int)InvStoreType.通用
                            });
                            ex.UpdatedBy = userNo;
                            ex.UpdatedDate = DateTime.Now;
                            ex.RelatedId = null;
                            ex.ProductId = null;
                            ex.LotNo = null;
                            updateEx.Add(ex);
                        }
                        if (item.InvStoreType == (int)InvStoreType.物料绑定)
                        {
                            updateStg.Add(stg);
                        }
                        if (item.InvStoreType == (int)InvStoreType.按生产订单)
                        {
                            delStg.Add(stg);
                            var ex = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity
                            {
                                LocationId = item.LocationId,
                                ProductId = item.ProductId,
                                Type = item.InvStoreType,
                                RelatedId = oo.RelatedId
                            });
                            int count = DataAccess.Select<InvWhLocationExEntity>(new InvWhLocationExEntity
                            {
                                LocationId = item.LocationId,
                                Type = item.InvStoreType,
                                RelatedId = oo.RelatedId
                            }).Count;
                            if (count > 1)
                            {
                                delEx.Add(ex);
                            }
                            else
                            {
                                ex.UpdatedBy = userNo;
                                ex.UpdatedDate = DateTime.Now;
                                ex.Type = (int)InvStoreType.通用;
                                ex.RelatedId = null;
                                ex.ProductId = null;
                                ex.LotNo = null;
                                updateEx.Add(ex);
                            }
                        }
                        if (item.InvStoreType == (int)InvStoreType.按采购到货)
                        {
                            delStg.Add(stg);
                            var ex = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity
                            {
                                LocationId = item.LocationId,
                                ProductId = item.ProductId,
                                Type = item.InvStoreType,
                                RelatedId = oo.RelatedId,
                                LotNo = item.LotNo
                            });
                            ex.UpdatedBy = userNo;
                            ex.UpdatedDate = DateTime.Now;
                            ex.Type = (int)InvStoreType.通用;
                            ex.RelatedId = null;
                            ex.ProductId = null;
                            ex.LotNo = null;
                            updateEx.Add(ex);
                        }
                        if (item.InvStoreType == (int)InvStoreType.自定义)
                        {
                            delStg.Add(stg);
                            var ex = DataAccess.SelectSingle<InvWhLocationExEntity>(new InvWhLocationExEntity
                            {
                                LocationId = item.LocationId,
                                ProductId = item.ProductId,
                                Type = item.InvStoreType
                            });
                            ex.UpdatedBy = userNo;
                            ex.UpdatedDate = DateTime.Now;
                            ex.Type = (int)InvStoreType.通用;
                            ex.RelatedId = null;
                            ex.ProductId = null;
                            ex.LotNo = null;
                            updateEx.Add(ex);
                        }
                    }
                    else
                    {
                        updateStg.Add(stg);
                    }
                }

                var stgHis = new InvStgHisEntity();
                stgHis.Id = Guid.NewGuid().ToString();
                stgHis.ProductId = item.ProductId;
                stgHis.Type = oo.Type;
                if (!string.IsNullOrEmpty(oo.RelatedId))
                    stgHis.RelatedId = oo.RelatedId;
                stgHis.LocationId = item.LocationId;
                stgHis.QtyOut = item.Qty;
                stgHis.CreatedBy = userNo;
                stgHis.CreatedDate = DateTime.Now;
                addStgHis.Add(stgHis);
            }

            oo.Status = WfStatus.WFS30.ToString();
            oapp.Status = WfStatus.WFS30.ToString();
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    broker.BeginTransaction();
                    DataAccess.Update(updateStg, broker);
                    DataAccess.Delete(delStg, broker);
                    DataAccess.Insert(addStgHis, broker);
                    DataAccess.Update(updateEx, broker);
                    DataAccess.Delete(delEx, broker);
                    DataAccess.Update(oo, broker);
                    DataAccess.Update(oapp, broker);
                    broker.Commit();
                    return new InvStockOutResultMessage { Result = true };
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    return new InvStockOutResultMessage { Result = false, Message = "保存失败" };
                }
            }
        }


        //InvWhItemEx
        public List<InvWhItemExDto> GetInvWhItemExDtoAllListByWhId(string whId)
        {
            if (string.IsNullOrEmpty(whId))
                return null;
            var items = DataAccess.Select<InvWhItemExEntity>(new InvWhItemExEntity { WhId = whId });
            if (items != null)
            {
                List<InvWhItemExDto> dtos = new List<InvWhItemExDto>();
                foreach (var item in items)
                {
                    Mapper.CreateMap<InvWhItemExEntity, InvWhItemExDto>();
                    var dto = AutoMapper.Mapper.Map<InvWhItemExEntity, InvWhItemExDto>(item);
                    var productType = DataAccess.SelectSingle<MstProductTypeEntity>(new MstProductTypeEntity { ProductTypeId = item.ProductTypeId });
                    if (productType != null)
                    {
                        dto.ProductTypeName = productType.ProductTypeName;
                    }
                    dtos.Add(dto);
                }
                return dtos;
            }
            else return null;
        }

        public bool SaveInvWhItemExDto(List<InvWhItemExDto> param)
        {
            if (param == null)
                return false;
            List<InvWhItemExEntity> items = new List<InvWhItemExEntity>();
            foreach (var dto in param)
            {
                Mapper.CreateMap<InvWhItemExDto, InvWhItemExEntity>();
                var item = AutoMapper.Mapper.Map<InvWhItemExDto, InvWhItemExEntity>(dto);
                items.Add(item);
            }
            return DataAccess.Insert(items);

        }

        public bool DelInvWhItemExDto(InvWhItemExDto dto)
        {
            if (dto == null)
                return false;
            var whItemEx = DataAccess.SelectSingle<InvWhItemExEntity>(new InvWhItemExEntity { Id = dto.Id });
            if (whItemEx != null)
            {
                return DataAccess.Delete(whItemEx);
            }
            else
            {
                return false;
            }

        }


        #endregion

        #region 工单领退料交易

        public InvMaintainMtrlTrans AddInvMtrlTransAndItem(InvMaintainMtrlTrans mtrlRequisition, List<InvMtrlTransItemEntity> Mtrls)
        {
            InvMtrlTransEntity input = Common.CommonFunction.CopyEntityToServiceOutPut<InvMtrlTransEntity, InvMaintainMtrlTrans>(mtrlRequisition);

            InvMtrlTransEntity tran = InvMtrlTransBs.AddInvMtrlTransAndItem(input, Mtrls);
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));
            mtrlRequisition.TransNo = tran.TransNo;
            if (!string.IsNullOrEmpty(tran.CreatedBy))
            {
                var createdUser = ps.getUser(null, tran.CreatedBy);
                mtrlRequisition.CreatedUser = createdUser.firstName;
            }
            if (!string.IsNullOrEmpty(tran.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, tran.UpdatedBy);
                mtrlRequisition.UpdatedUser = updatedUser.firstName;
            }
            return mtrlRequisition;
        }


        public InvMaintainMtrlTrans UpdateInvMtrlTransAndItem(InvMaintainMtrlTrans mtrlRequisition, List<InvMtrlTransItemEntity> Mtrls)
        {
            InvMtrlTransEntity input = Common.CommonFunction.CopyEntityToServiceOutPut<InvMtrlTransEntity, InvMaintainMtrlTrans>(mtrlRequisition);
            InvMtrlTransEntity tran = InvMtrlTransBs.UpdateInvMtrlTransAndItem(input, Mtrls);
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));
            if (!string.IsNullOrEmpty(tran.CreatedBy))
            {
                var createdUser = ps.getUser(null, tran.CreatedBy);
                mtrlRequisition.CreatedUser = createdUser.firstName;
            }
            if (!string.IsNullOrEmpty(tran.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, tran.UpdatedBy);
                mtrlRequisition.UpdatedUser = updatedUser.firstName;
            }
            return mtrlRequisition;
        }

        public bool DeleteInvMtrlTransAndItem(InvMaintainMtrlTrans mtrlRequisition)
        {
            InvMtrlTransEntity input = Common.CommonFunction.CopyEntityToServiceOutPut<InvMtrlTransEntity, InvMaintainMtrlTrans>(mtrlRequisition);
            return InvMtrlTransBs.DeleteInvMtrlTransAndItem(input);
        }

        public InvMaintainMtrlTrans GetInvMtrlTransById(string id)
        {
            InvMtrlTransEntity tran = InvMtrlTransBs.GetInvMtrlTrans(new InvMtrlTransEntity { Id = id });
            InvMaintainMtrlTrans output = Common.CommonFunction.CopyEntityToServiceOutPut<InvMaintainMtrlTrans, InvMtrlTransEntity>(tran);
            string connectionString = MyConfig.getConnection("myconstring");
            PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));
            if (!string.IsNullOrEmpty(tran.CreatedBy))
            {
                var createdUser = ps.getUser(null, tran.CreatedBy);
                output.CreatedUser = createdUser.firstName;
            }
            if (!string.IsNullOrEmpty(tran.UpdatedBy))
            {
                var updatedUser = ps.getUser(null, tran.UpdatedBy);
                output.UpdatedUser = updatedUser.firstName;
            }
            return output;
        }

        public List<InvMaintainMtrlTrans> GetInvMtrlTransByCondition(InvMtrlTransQueryCondition condition)
        {
            List<InvMtrlTransEntity> trans;
            if (condition == null)
                trans = InvMtrlTransBs.GetInvMtrlTransAllList();
            else
                trans = InvMtrlTransBs.GetInvMtrlTransByCondition(condition);
            List<InvMaintainMtrlTrans> Outputs = new List<InvMaintainMtrlTrans>();
            if (trans != null)
            {
                string connectionString = MyConfig.getConnection("myconstring");
                PowerService ps = new PowerService(new BPM.Foundation.PWDB.PWDBDataContext(connectionString));

                foreach (InvMtrlTransEntity tran in trans)
                {
                    InvMaintainMtrlTrans output = Common.CommonFunction.CopyEntityToServiceOutPut<InvMaintainMtrlTrans, InvMtrlTransEntity>(tran);
                    if (!string.IsNullOrEmpty(tran.CreatedBy))
                    {
                        var createdUser = ps.getUser(null, tran.CreatedBy);
                        output.CreatedUser = createdUser.firstName;
                    }
                    if (!string.IsNullOrEmpty(tran.UpdatedBy))
                    {
                        var updatedUser = ps.getUser(null, tran.UpdatedBy);
                        output.UpdatedUser = updatedUser.firstName;
                    }
                    Outputs.Add(output);
                }
            }
            return Outputs;
        }


        public List<InvMtrlTransItemEntity> GetInvMtrlTransItemByTransNo(string transNo)
        {
            return InvMtrlTransItemBs.GetInvMtrlTransItemByTransNo(transNo);
        }


        public DataSet GetInvLocsDsByMtrlId(string mtrlId)
        {
            if (string.IsNullOrEmpty(mtrlId))
                return null;
            string sql = @"SELECT loc.*,prod.PRODUCT_NAME,null as RELATED_NO,stg.CURRENT_QTY,prod.PRODUCT_CODE
FROM INV_STG stg
left join INV_WH_LOCATION loc on loc.ID=stg.LOCATION_ID 
left join MST_PRODUCT prod on stg.PRODUCT_ID=prod.PRODUCT_ID
where loc.id is not null and stg.PRODUCT_ID='{0}'";
            sql = string.Format(sql, mtrlId);
            return InvWhLocationBs.GetWhLocsBySql(sql);
        }

        public string InvOutWfStart(InvMaintainOApp trans)
        {
            try
            {
                InvOappEntity tranEntity = InvOappBs.GetInvOapp(new InvOappEntity { Id = trans.Id });
                bool re = InvOappBs.InvOutWfStart(tranEntity);
                if (re)
                    return "";
                else
                    return "ProdMtrlRequisitionWfStart:修改表单" + trans.RelatedId + " 状态失败！";
            }
            catch (Exception ex)
            {
                return "ProdMtrlRequisitionWfStart:" + ex.Message;
            }
        }

        public string InvInWfStart(InvMaintainIApp trans)
        {
            try
            {
                InvIappEntity tranEntity = InvIappBs.GetInvIapp(new InvIappEntity { Id = trans.Id });
                bool re = InvIappBs.InvInWfStart(tranEntity);
                if (re)
                    return "";
                else
                    return "InvInWfStart:修改表单" + trans.RelatedId + " 状态失败！";
            }
            catch (Exception ex)
            {
                return "InvInWfStart:" + ex.Message;
            }
        }


        public decimal GetAllowReqMaxQty(string woNo, string transNo, string mtrlId)
        {
            try
            {

                return InvMtrlTransBs.GetAllowReqMaxQty(woNo, transNo, mtrlId);

            }
            catch (Exception ex)
            {
                return 0;
            }
        }

        public decimal GetAllowReturnMaxQty(string woNo, string transNo, string mtrlCode)
        {
            try
            {

                return InvMtrlTransBs.GetAllowReturnMaxQty(woNo, transNo, mtrlCode);

            }
            catch (Exception ex)
            {
                return 0;
            }
        }

        #endregion
    }
}
